122
103
? ((CC).giga_no--, (CC).no = ONE_GIGA - 1) \
129
#define MSEG_ALLOC(A, SP) \
130
(INC_CC((A)->calls.mseg_alloc), \
131
erts_mseg_alloc_opt((SP), &(A)->mseg_opt))
133
#define MSEG_DEALLOC(A, C, S) \
134
(INC_CC((A)->calls.mseg_dealloc), \
135
erts_mseg_dealloc_opt((void *) (C), (S), &(A)->mseg_opt))
137
#define MSEG_REALLOC(A, C, OS, SP) \
138
(INC_CC((A)->calls.mseg_realloc), \
139
erts_mseg_realloc_opt((void *) (C), (OS), (SP), &(A)->mseg_opt))
147
#define SYS_ALLOC(A,S) (INC_CC((A)->calls.sys_alloc), \
148
erts_sys_alloc(0, NULL, (S)))
149
#define SYS_REALLOC(A,P,S) (INC_CC((A)->calls.sys_realloc), \
150
erts_sys_realloc(0, NULL, (P), (S)))
151
#define SYS_FREE(A,P) (INC_CC((A)->calls.sys_free), \
152
erts_sys_free(0, NULL, (P)))
468
420
#define DEBUG_CHECK_ALIGNMENT(P)
423
static void make_name_atoms(Allctr_t *allctr);
430
static ERTS_INLINE void *
431
alcu_mseg_alloc(Allctr_t *allctr, Uint *size_p)
435
res = erts_mseg_alloc_opt(allctr->alloc_no, size_p, &allctr->mseg_opt);
436
INC_CC(allctr->calls.mseg_alloc);
440
static ERTS_INLINE void *
441
alcu_mseg_realloc(Allctr_t *allctr, void *seg, Uint old_size, Uint *new_size_p)
445
res = erts_mseg_realloc_opt(allctr->alloc_no, seg, old_size, new_size_p,
447
INC_CC(allctr->calls.mseg_realloc);
451
static ERTS_INLINE void
452
alcu_mseg_dealloc(Allctr_t *allctr, void *seg, Uint size)
454
erts_mseg_dealloc_opt(allctr->alloc_no, seg, size, &allctr->mseg_opt);
455
INC_CC(allctr->calls.mseg_dealloc);
460
static ERTS_INLINE void *
461
alcu_sys_alloc(Allctr_t *allctr, Uint size)
465
res = erts_sys_alloc(0, NULL, size);
466
INC_CC(allctr->calls.sys_alloc);
467
if (erts_mtrace_enabled)
468
erts_mtrace_crr_alloc(res, allctr->alloc_no, ERTS_ALC_A_SYSTEM, size);
472
static ERTS_INLINE void *
473
alcu_sys_realloc(Allctr_t *allctr, void *ptr, Uint size)
477
res = erts_sys_realloc(0, NULL, ptr, size);
478
INC_CC(allctr->calls.sys_realloc);
479
if (erts_mtrace_enabled)
480
erts_mtrace_crr_realloc(res,
488
static ERTS_INLINE void
489
alcu_sys_free(Allctr_t *allctr, void *ptr)
491
erts_sys_free(0, NULL, ptr);
492
INC_CC(allctr->calls.sys_free);
493
if (erts_mtrace_enabled)
494
erts_mtrace_crr_free(allctr->alloc_no, ERTS_ALC_A_SYSTEM, ptr);
473
498
get_next_mbc_size(Allctr_t *allctr)
1441
1475
#define AM_INIT(AM) atom_init(&am.AM, #AM)
1477
static erts_mtx_t init_atoms_mtx;
1480
init_atoms(Allctr_t *allctr)
1448
for (atom = (Eterm *) &am; atom <= &am.end_of_atoms; atom++) {
1449
*atom = THE_NON_VALUE;
1480
AM_INIT(sys_alloc_carriers_size);
1482
AM_INIT(mseg_alloc_carriers_size);
1484
AM_INIT(carriers_size);
1485
AM_INIT(sys_alloc_carriers);
1487
AM_INIT(mseg_alloc_carriers);
1490
AM_INIT(blocks_size);
1496
AM_INIT(sys_realloc);
1498
AM_INIT(mseg_alloc);
1499
AM_INIT(mseg_dealloc);
1500
AM_INIT(mseg_realloc);
1504
for (atom = (Eterm *) &am; atom < &am.end_of_atoms; atom++) {
1505
ASSERT(*atom != THE_NON_VALUE);
1484
if (allctr && allctr->thread_safe)
1485
erts_mtx_unlock(&allctr->mutex);
1488
erts_mtx_lock(&init_atoms_mtx);
1490
if (!atoms_initialized) {
1494
for (atom = (Eterm *) &am; atom <= &am.end_of_atoms; atom++) {
1495
*atom = THE_NON_VALUE;
1526
AM_INIT(sys_alloc_carriers_size);
1528
AM_INIT(mseg_alloc_carriers_size);
1530
AM_INIT(carriers_size);
1531
AM_INIT(sys_alloc_carriers);
1533
AM_INIT(mseg_alloc_carriers);
1536
AM_INIT(blocks_size);
1542
AM_INIT(sys_realloc);
1544
AM_INIT(mseg_alloc);
1545
AM_INIT(mseg_dealloc);
1546
AM_INIT(mseg_realloc);
1550
for (atom = (Eterm *) &am; atom < &am.end_of_atoms; atom++) {
1551
ASSERT(*atom != THE_NON_VALUE);
1559
make_name_atoms(allctr);
1561
(*allctr->init_atoms)();
1564
if (allctr->thread_safe)
1565
erts_mtx_lock(&allctr->mutex);
1567
allctr->atoms_initialized = 1;
1509
1570
atoms_initialized = 1;
1571
erts_mtx_unlock(&init_atoms_mtx);
1575
static ERTS_INLINE void
1576
ensure_atoms_initialized(Allctr_t *allctr)
1578
if (!allctr || !allctr->atoms_initialized)
1513
1582
#define bld_uint erts_bld_uint
1514
1583
#define bld_cons erts_bld_cons
1515
1584
#define bld_tuple erts_bld_tuple
1516
1585
#define bld_string erts_bld_string
1588
* bld_unstable_uint() (instead bld_uint()) is used when values may
1589
* change between size check and actual build. This because a value
1590
* that would fit a small when size check is done may need to be built
1591
* as a big when the actual build is performed. Caller is required to
1592
* HRelease after build.
1594
static ERTS_INLINE Eterm
1595
bld_unstable_uint(Uint **hpp, Uint *szp, Uint ui)
1597
Eterm res = THE_NON_VALUE;
1599
szp += BIG_UINT_HEAP_SIZE;
1601
if (IS_USMALL(0, ui))
1602
res = make_small(ui);
1604
res = uint_to_big(ui, *hpp);
1605
*hpp += BIG_UINT_HEAP_SIZE;
1518
1611
static ERTS_INLINE void
1519
1612
add_2tup(Uint **hpp, Uint *szp, Eterm *lp, Eterm el1, Eterm el2)
1547
1641
Uint curr_no = cs->curr_mseg.no + cs->curr_sys_alloc.no;
1548
1642
Uint curr_size = cs->curr_mseg.size + cs->curr_sys_alloc.size;
1553
"%sblocks: %lu %lu %lu\n",
1645
int to = *print_to_p;
1646
void *arg = print_to_arg;
1649
"%sblocks: %bpu %bpu %bpu\n",
1555
1651
cs->blocks.curr.no,
1556
1652
cs->blocks.max.no,
1557
1653
cs->blocks.max_ever.no);
1559
"%sblocks size: %lu %lu %lu\n",
1656
"%sblocks size: %bpu %bpu %bpu\n",
1561
1658
cs->blocks.curr.size,
1562
1659
cs->blocks.max.size,
1563
1660
cs->blocks.max_ever.size);
1565
"%scarriers: %lu %lu %lu\n",
1663
"%scarriers: %bpu %bpu %bpu\n",
1569
1667
cs->max_ever.no);
1570
1668
#if HAVE_ERTS_MSEG
1572
"%smseg carriers: %lu\n",
1671
"%smseg carriers: %bpu\n",
1574
1673
cs->curr_mseg.no);
1577
"%ssys_alloc carriers: %lu\n",
1677
"%ssys_alloc carriers: %bpu\n",
1579
1679
cs->curr_sys_alloc.no);
1581
"%scarriers size: %lu %lu %lu\n",
1682
"%scarriers size: %bpu %bpu %bpu\n",
1585
1686
cs->max_ever.size);
1586
1687
#if HAVE_ERTS_MSEG
1588
"%smseg carriers size: %lu\n",
1690
"%smseg carriers size: %bpu\n",
1590
1692
cs->curr_mseg.size);
1593
"%ssys_alloc carriers size: %lu\n",
1696
"%ssys_alloc carriers size: %bpu\n",
1595
1698
cs->curr_sys_alloc.size);
1600
1703
add_2tup(hpp, szp, &res,
1601
1704
am.sys_alloc_carriers_size,
1602
bld_uint(hpp, szp, cs->curr_sys_alloc.size));
1705
bld_unstable_uint(hpp, szp, cs->curr_sys_alloc.size));
1603
1706
#if HAVE_ERTS_MSEG
1604
1707
add_2tup(hpp, szp, &res,
1605
1708
am.mseg_alloc_carriers_size,
1606
bld_uint(hpp, szp, cs->curr_mseg.size));
1709
bld_unstable_uint(hpp, szp, cs->curr_mseg.size));
1608
1711
add_4tup(hpp, szp, &res,
1609
1712
am.carriers_size,
1610
bld_uint(hpp, szp, curr_size),
1611
bld_uint(hpp, szp, cs->max.size),
1612
bld_uint(hpp, szp, cs->max_ever.size));
1713
bld_unstable_uint(hpp, szp, curr_size),
1714
bld_unstable_uint(hpp, szp, cs->max.size),
1715
bld_unstable_uint(hpp, szp, cs->max_ever.size));
1613
1716
add_2tup(hpp, szp, &res,
1614
1717
am.sys_alloc_carriers,
1615
bld_uint(hpp, szp, cs->curr_sys_alloc.no));
1718
bld_unstable_uint(hpp, szp, cs->curr_sys_alloc.no));
1616
1719
#if HAVE_ERTS_MSEG
1617
1720
add_2tup(hpp, szp, &res,
1618
1721
am.mseg_alloc_carriers,
1619
bld_uint(hpp, szp, cs->curr_mseg.no));
1722
bld_unstable_uint(hpp, szp, cs->curr_mseg.no));
1621
1724
add_4tup(hpp, szp, &res,
1623
bld_uint(hpp, szp, curr_no),
1624
bld_uint(hpp, szp, cs->max.no),
1625
bld_uint(hpp, szp, cs->max_ever.no));
1726
bld_unstable_uint(hpp, szp, curr_no),
1727
bld_unstable_uint(hpp, szp, cs->max.no),
1728
bld_unstable_uint(hpp, szp, cs->max_ever.no));
1626
1729
add_4tup(hpp, szp, &res,
1627
1730
am.blocks_size,
1628
bld_uint(hpp, szp, cs->blocks.curr.size),
1629
bld_uint(hpp, szp, cs->blocks.max.size),
1630
bld_uint(hpp, szp, cs->blocks.max_ever.size));
1731
bld_unstable_uint(hpp, szp, cs->blocks.curr.size),
1732
bld_unstable_uint(hpp, szp, cs->blocks.max.size),
1733
bld_unstable_uint(hpp, szp, cs->blocks.max_ever.size));
1631
1734
add_4tup(hpp, szp, &res,
1633
bld_uint(hpp, szp, cs->blocks.curr.no),
1634
bld_uint(hpp, szp, cs->blocks.max.no),
1635
bld_uint(hpp, szp, cs->blocks.max_ever.no));
1736
bld_unstable_uint(hpp, szp, cs->blocks.curr.no),
1737
bld_unstable_uint(hpp, szp, cs->blocks.max.no),
1738
bld_unstable_uint(hpp, szp, cs->blocks.max_ever.no));
1667
1770
info_calls(Allctr_t *allctr,
1672
1776
Eterm res = THE_NON_VALUE;
1677
#define PRINT_CC_3(TO, NAME, CC) \
1678
if ((CC).giga_no == 0) \
1679
erl_printf(TO, "%s calls: %lu\n", NAME, CC.no); \
1681
erl_printf(TO, "%s calls: %lu%09lu\n", NAME, CC.giga_no, CC.no)
1683
#define PRINT_CC_4(TO, PRFX, NAME, CC) \
1684
if ((CC).giga_no == 0) \
1685
erl_printf(TO,"%s%s calls: %lu\n",PRFX,NAME,CC.no); \
1687
erl_printf(TO,"%s%s calls: %lu%09lu\n",PRFX,NAME,CC.giga_no,CC.no)
1781
#define PRINT_CC_4(TO, TOA, NAME, CC) \
1782
if ((CC).giga_no == 0) \
1783
erts_print(TO, TOA, "%s calls: %bpu\n", NAME, CC.no); \
1785
erts_print(TO, TOA, "%s calls: %bpu%09lu\n", NAME, CC.giga_no, CC.no)
1787
#define PRINT_CC_5(TO, TOA, PRFX, NAME, CC) \
1788
if ((CC).giga_no == 0) \
1789
erts_print(TO, TOA, "%s%s calls: %bpu\n",PRFX,NAME,CC.no); \
1791
erts_print(TO, TOA, "%s%s calls: %bpu%09lu\n",PRFX,NAME,CC.giga_no,CC.no)
1689
1793
char *prefix = allctr->name_prefix;
1794
int to = *print_to_p;
1795
void *arg = print_to_arg;
1692
PRINT_CC_4(to, prefix, "alloc", allctr->calls.this_alloc);
1693
PRINT_CC_4(to, prefix, "free", allctr->calls.this_free);
1694
PRINT_CC_4(to, prefix, "realloc", allctr->calls.this_realloc);
1797
PRINT_CC_5(to, arg, prefix, "alloc", allctr->calls.this_alloc);
1798
PRINT_CC_5(to, arg, prefix, "free", allctr->calls.this_free);
1799
PRINT_CC_5(to, arg, prefix, "realloc", allctr->calls.this_realloc);
1696
1801
#if HAVE_ERTS_MSEG
1697
PRINT_CC_3(to, "mseg_alloc", allctr->calls.mseg_alloc);
1698
PRINT_CC_3(to, "mseg_dealloc", allctr->calls.mseg_dealloc);
1699
PRINT_CC_3(to, "mseg_realloc", allctr->calls.mseg_realloc);
1802
PRINT_CC_4(to, arg, "mseg_alloc", allctr->calls.mseg_alloc);
1803
PRINT_CC_4(to, arg, "mseg_dealloc", allctr->calls.mseg_dealloc);
1804
PRINT_CC_4(to, arg, "mseg_realloc", allctr->calls.mseg_realloc);
1702
PRINT_CC_3(to, "sys_alloc", allctr->calls.sys_alloc);
1703
PRINT_CC_3(to, "sys_free", allctr->calls.sys_free);
1704
PRINT_CC_3(to, "sys_realloc", allctr->calls.sys_realloc);
1807
PRINT_CC_4(to, arg, "sys_alloc", allctr->calls.sys_alloc);
1808
PRINT_CC_4(to, arg, "sys_free", allctr->calls.sys_free);
1809
PRINT_CC_4(to, arg, "sys_realloc", allctr->calls.sys_realloc);
1707
1811
#undef PRINT_CC_4
1712
1817
if (hpp || szp) {
1713
if (allctr->name.alloc == THE_NON_VALUE)
1714
make_name_atoms(allctr);
1716
1819
ASSERT(allctr->name.alloc != THE_NON_VALUE);
1717
1820
ASSERT(allctr->name.realloc != THE_NON_VALUE);
1722
1825
add_3tup(hpp, szp, &res,
1723
1826
am.sys_realloc,
1724
bld_uint(hpp, szp, allctr->calls.sys_realloc.giga_no),
1725
bld_uint(hpp, szp, allctr->calls.sys_realloc.no));
1827
bld_unstable_uint(hpp, szp, allctr->calls.sys_realloc.giga_no),
1828
bld_unstable_uint(hpp, szp, allctr->calls.sys_realloc.no));
1726
1829
add_3tup(hpp, szp, &res,
1728
bld_uint(hpp, szp, allctr->calls.sys_free.giga_no),
1729
bld_uint(hpp, szp, allctr->calls.sys_free.no));
1831
bld_unstable_uint(hpp, szp, allctr->calls.sys_free.giga_no),
1832
bld_unstable_uint(hpp, szp, allctr->calls.sys_free.no));
1730
1833
add_3tup(hpp, szp, &res,
1732
bld_uint(hpp, szp, allctr->calls.sys_alloc.giga_no),
1733
bld_uint(hpp, szp, allctr->calls.sys_alloc.no));
1835
bld_unstable_uint(hpp, szp, allctr->calls.sys_alloc.giga_no),
1836
bld_unstable_uint(hpp, szp, allctr->calls.sys_alloc.no));
1734
1837
#if HAVE_ERTS_MSEG
1735
1838
add_3tup(hpp, szp, &res,
1736
1839
am.mseg_realloc,
1737
bld_uint(hpp, szp, allctr->calls.mseg_realloc.giga_no),
1738
bld_uint(hpp, szp, allctr->calls.mseg_realloc.no));
1840
bld_unstable_uint(hpp, szp, allctr->calls.mseg_realloc.giga_no),
1841
bld_unstable_uint(hpp, szp, allctr->calls.mseg_realloc.no));
1739
1842
add_3tup(hpp, szp, &res,
1740
1843
am.mseg_dealloc,
1741
bld_uint(hpp, szp, allctr->calls.mseg_dealloc.giga_no),
1742
bld_uint(hpp, szp, allctr->calls.mseg_dealloc.no));
1844
bld_unstable_uint(hpp, szp, allctr->calls.mseg_dealloc.giga_no),
1845
bld_unstable_uint(hpp, szp, allctr->calls.mseg_dealloc.no));
1743
1846
add_3tup(hpp, szp, &res,
1745
bld_uint(hpp, szp, allctr->calls.mseg_alloc.giga_no),
1746
bld_uint(hpp, szp, allctr->calls.mseg_alloc.no));
1848
bld_unstable_uint(hpp, szp, allctr->calls.mseg_alloc.giga_no),
1849
bld_unstable_uint(hpp, szp, allctr->calls.mseg_alloc.no));
1748
1851
add_3tup(hpp, szp, &res,
1749
1852
allctr->name.realloc,
1750
bld_uint(hpp, szp, allctr->calls.this_realloc.giga_no),
1751
bld_uint(hpp, szp, allctr->calls.this_realloc.no));
1853
bld_unstable_uint(hpp, szp, allctr->calls.this_realloc.giga_no),
1854
bld_unstable_uint(hpp, szp, allctr->calls.this_realloc.no));
1752
1855
add_3tup(hpp, szp, &res,
1753
1856
allctr->name.free,
1754
bld_uint(hpp, szp, allctr->calls.this_free.giga_no),
1755
bld_uint(hpp, szp, allctr->calls.this_free.no));
1857
bld_unstable_uint(hpp, szp, allctr->calls.this_free.giga_no),
1858
bld_unstable_uint(hpp, szp, allctr->calls.this_free.no));
1756
1859
add_3tup(hpp, szp, &res,
1757
1860
allctr->name.alloc,
1758
bld_uint(hpp, szp, allctr->calls.this_alloc.giga_no),
1759
bld_uint(hpp, szp, allctr->calls.this_alloc.no));
1861
bld_unstable_uint(hpp, szp, allctr->calls.this_alloc.giga_no),
1862
bld_unstable_uint(hpp, szp, allctr->calls.this_alloc.no));
1989
2089
update_max_ever_values(&allctr->mbcs);
1990
2090
update_max_ever_values(&allctr->sbcs);
2093
erts_print(*print_to_p,
1994
2095
"versions: %s %s\n",
1995
2096
allctr->vsn_str,
1996
2097
ERTS_ALCU_VSN_STR);
1999
sett = info_options(allctr, ciop, hpp, szp);
2000
mbcs = info_carriers(allctr, &allctr->mbcs, "mbcs ", ciop, hpp, szp);
2001
sbcs = info_carriers(allctr, &allctr->sbcs, "sbcs ", ciop, hpp, szp);
2002
calls = info_calls(allctr, ciop, hpp, szp);
2100
sett = info_options(allctr, print_to_p, print_to_arg, hpp, szp);
2101
mbcs = info_carriers(allctr, &allctr->mbcs, "mbcs ", print_to_p,
2102
print_to_arg, hpp, szp);
2103
sbcs = info_carriers(allctr, &allctr->sbcs, "sbcs ", print_to_p,
2104
print_to_arg, hpp, szp);
2105
calls = info_calls(allctr, print_to_p, print_to_arg, hpp, szp);
2004
2107
if (hpp || szp) {
2007
if (!atoms_initialized)
2010
2110
add_2tup(hpp, szp, &res, am.calls, calls);
2011
2111
add_2tup(hpp, szp, &res, am.sbcs, sbcs);
2012
2112
add_2tup(hpp, szp, &res, am.mbcs, mbcs);
2076
2176
Allctr_t *allctr = (Allctr_t *) extra;
2078
LOCK(allctr->mutex);
2178
erts_mtx_lock(&allctr->mutex);
2079
2179
res = do_erts_alcu_alloc(type, extra, size);
2080
UNLOCK(allctr->mutex);
2180
erts_mtx_unlock(&allctr->mutex);
2184
#ifdef ERTS_ALC_THR_SPEC_ALLOCS
2186
erts_alcu_alloc_thr_spec(ErtsAlcType_t type, void *unused, Uint size)
2188
void *vallctr = erts_tsd_get(erts_allctr_thr_spec[ERTS_ALC_T2A(T)].key);
2191
vallctr = (*erts_allctr_thr_spec[ERTS_ALC_T2A(type)].start_default)();
2196
return do_erts_alcu_alloc(type, vallctr, size);
2086
2202
/* ------------------------------------------------------------------------- */
2228
2354
Allctr_t *allctr = (Allctr_t *) extra;
2230
LOCK(allctr->mutex);
2356
erts_mtx_lock(&allctr->mutex);
2231
2357
res = do_erts_alcu_realloc(type, extra, ptr, size);
2232
UNLOCK(allctr->mutex);
2358
erts_mtx_unlock(&allctr->mutex);
2362
#ifdef ERTS_ALC_THR_SPEC_ALLOCS
2364
erts_alcu_realloc_thr_spec(ErtsAlcType_t type, void *unused,
2365
void *ptr, Uint size)
2367
void *vallctr = erts_tsd_get(erts_allctr_thr_spec[ERTS_ALC_T2A(T)].key);
2370
vallctr = (*erts_allctr_thr_spec[ERTS_ALC_T2A(type)].start_default)();
2375
return do_erts_alcu_realloc(type, vallctr, ptr, size);
2238
2381
/* ------------------------------------------------------------------------- */