aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/beam/erl_alloc_util.h
diff options
context:
space:
mode:
Diffstat (limited to 'erts/emulator/beam/erl_alloc_util.h')
-rw-r--r--erts/emulator/beam/erl_alloc_util.h342
1 files changed, 342 insertions, 0 deletions
diff --git a/erts/emulator/beam/erl_alloc_util.h b/erts/emulator/beam/erl_alloc_util.h
new file mode 100644
index 0000000000..10b11661e6
--- /dev/null
+++ b/erts/emulator/beam/erl_alloc_util.h
@@ -0,0 +1,342 @@
+/*
+ * %CopyrightBegin%
+ *
+ * Copyright Ericsson AB 2002-2009. All Rights Reserved.
+ *
+ * The contents of this file are subject to the Erlang Public License,
+ * Version 1.1, (the "License"); you may not use this file except in
+ * compliance with the License. You should have received a copy of the
+ * Erlang Public License along with this software. If not, it can be
+ * retrieved online at http://www.erlang.org/.
+ *
+ * Software distributed under the License is distributed on an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+ * the License for the specific language governing rights and limitations
+ * under the License.
+ *
+ * %CopyrightEnd%
+ */
+
+#ifndef ERL_ALLOC_UTIL__
+#define ERL_ALLOC_UTIL__
+
+#define ERTS_ALCU_VSN_STR "2.2"
+
+#include "erl_alloc_types.h"
+
+typedef struct Allctr_t_ Allctr_t;
+
+typedef struct {
+ Uint ycs;
+ Uint mmc;
+} AlcUInit_t;
+
+typedef struct {
+ char *name_prefix;
+ ErtsAlcType_t alloc_no;
+ int ts;
+ int tspec;
+ int tpref;
+ int ramv;
+ Uint sbct;
+ Uint asbcst;
+ Uint rsbcst;
+ Uint rsbcmt;
+ Uint rmbcmt;
+ Uint mmbcs;
+ Uint mmsbc;
+ Uint mmmbc;
+ Uint lmbcs;
+ Uint smbcs;
+ Uint mbcgs;
+} AllctrInit_t;
+
+typedef struct {
+ Uint blocks;
+ Uint carriers;
+} AllctrSize_t;
+
+#ifndef SMALL_MEMORY
+
+#define ERTS_DEFAULT_ALCU_INIT { \
+ 1024*1024, /* (bytes) ycs: sys_alloc carrier size */\
+ 1024 /* (amount) mmc: max mseg carriers */\
+}
+
+#define ERTS_DEFAULT_ALLCTR_INIT { \
+ NULL, \
+ ERTS_ALC_A_INVALID, /* (number) alloc_no: allocator number */\
+ 1, /* (bool) ts: thread safe */\
+ 0, /* (bool) tspec: thread specific */\
+ 0, /* (bool) tpref: thread preferred */\
+ 0, /* (bool) ramv: realloc always moves */\
+ 512*1024, /* (bytes) sbct: sbc threshold */\
+ 2*1024*2024, /* (amount) asbcst: abs sbc shrink threshold */\
+ 20, /* (%) rsbcst: rel sbc shrink threshold */\
+ 80, /* (%) rsbcmt: rel sbc move threshold */\
+ 50, /* (%) rmbcmt: rel mbc move threshold */\
+ 1024*1024, /* (bytes) mmbcs: main multiblock carrier size */\
+ 256, /* (amount) mmsbc: max mseg sbcs */\
+ 10, /* (amount) mmmbc: max mseg mbcs */\
+ 10*1024*1024, /* (bytes) lmbcs: largest mbc size */\
+ 1024*1024, /* (bytes) smbcs: smallest mbc size */\
+ 10 /* (amount) mbcgs: mbc growth stages */\
+}
+
+#else /* if SMALL_MEMORY */
+
+#define ERTS_DEFAULT_ALCU_INIT { \
+ 128*1024, /* (bytes) ycs: sys_alloc carrier size */\
+ 1024 /* (amount) mmc: max mseg carriers */\
+}
+
+#define ERTS_DEFAULT_ALLCTR_INIT { \
+ NULL, \
+ ERTS_ALC_A_INVALID, /* (number) alloc_no: allocator number */\
+ 1, /* (bool) ts: thread safe */\
+ 0, /* (bool) tspec: thread specific */\
+ 0, /* (bool) tpref: thread preferred */\
+ 0, /* (bool) ramv: realloc always moves */\
+ 64*1024, /* (bytes) sbct: sbc threshold */\
+ 2*1024*2024, /* (amount) asbcst: abs sbc shrink threshold */\
+ 20, /* (%) rsbcst: rel sbc shrink threshold */\
+ 80, /* (%) rsbcmt: rel sbc move threshold */\
+ 128*1024, /* (bytes) mmbcs: main multiblock carrier size */\
+ 256, /* (amount) mmsbc: max mseg sbcs */\
+ 10, /* (amount) mmmbc: max mseg mbcs */\
+ 1024*1024, /* (bytes) lmbcs: largest mbc size */\
+ 128*1024, /* (bytes) smbcs: smallest mbc size */\
+ 10 /* (amount) mbcgs: mbc growth stages */\
+}
+
+#endif
+
+void * erts_alcu_alloc(ErtsAlcType_t, void *, Uint);
+void * erts_alcu_realloc(ErtsAlcType_t, void *, void *, Uint);
+void * erts_alcu_realloc_mv(ErtsAlcType_t, void *, void *, Uint);
+void erts_alcu_free(ErtsAlcType_t, void *, void *);
+#ifdef USE_THREADS
+void * erts_alcu_alloc_ts(ErtsAlcType_t, void *, Uint);
+void * erts_alcu_realloc_ts(ErtsAlcType_t, void *, void *, Uint);
+void * erts_alcu_realloc_mv_ts(ErtsAlcType_t, void *, void *, Uint);
+void erts_alcu_free_ts(ErtsAlcType_t, void *, void *);
+void * erts_alcu_alloc_thr_spec(ErtsAlcType_t, void *, Uint);
+void * erts_alcu_realloc_thr_spec(ErtsAlcType_t, void *, void *, Uint);
+void * erts_alcu_realloc_mv_thr_spec(ErtsAlcType_t, void *, void *, Uint);
+void erts_alcu_free_thr_spec(ErtsAlcType_t, void *, void *);
+void * erts_alcu_alloc_thr_pref(ErtsAlcType_t, void *, Uint);
+void * erts_alcu_realloc_thr_pref(ErtsAlcType_t, void *, void *, Uint);
+void * erts_alcu_realloc_mv_thr_pref(ErtsAlcType_t, void *, void *, Uint);
+void erts_alcu_free_thr_pref(ErtsAlcType_t, void *, void *);
+#endif
+Eterm erts_alcu_au_info_options(int *, void *, Uint **, Uint *);
+Eterm erts_alcu_info_options(Allctr_t *, int *, void *, Uint **, Uint *);
+Eterm erts_alcu_sz_info(Allctr_t *, int, int *, void *, Uint **, Uint *);
+Eterm erts_alcu_info(Allctr_t *, int, int *, void *, Uint **, Uint *);
+void erts_alcu_init(AlcUInit_t *);
+void erts_alcu_current_size(Allctr_t *, AllctrSize_t *);
+
+#endif
+
+#if defined(GET_ERL_ALLOC_UTIL_IMPL) && !defined(ERL_ALLOC_UTIL_IMPL__)
+#define ERL_ALLOC_UTIL_IMPL__
+
+#ifdef USE_THREADS
+#define ERL_THREADS_EMU_INTERNAL__
+#include "erl_threads.h"
+#endif
+
+#include "erl_mseg.h"
+
+#undef ERTS_ALLOC_UTIL_HARD_DEBUG
+#ifdef DEBUG
+# if 0
+# define ERTS_ALLOC_UTIL_HARD_DEBUG
+# endif
+#endif
+
+#undef MIN
+#undef MAX
+#define MIN(X, Y) ((X) < (Y) ? (X) : (Y))
+#define MAX(X, Y) ((X) > (Y) ? (X) : (Y))
+#define FLOOR(X, I) (((X)/(I))*(I))
+#define CEILING(X, I) ((((X) - 1)/(I) + 1)*(I))
+
+#undef WORD_MASK
+#define INV_WORD_MASK ((Uint) (sizeof(Uint) - 1))
+#define WORD_MASK (~INV_WORD_MASK)
+#define WORD_FLOOR(X) ((X) & WORD_MASK)
+#define WORD_CEILING(X) WORD_FLOOR((X) + INV_WORD_MASK)
+
+#undef UNIT_MASK
+#define INV_UNIT_MASK ((Uint) (sizeof(Unit_t) - 1))
+#define UNIT_MASK (~INV_UNIT_MASK)
+#define UNIT_FLOOR(X) ((X) & UNIT_MASK)
+#define UNIT_CEILING(X) UNIT_FLOOR((X) + INV_UNIT_MASK)
+
+
+#define SZ_MASK (~((Uint) 0) << 3)
+#define FLG_MASK (~(SZ_MASK))
+
+
+#define BLK_SZ(B) \
+ (*((Block_t *) (B)) & SZ_MASK)
+
+#define CARRIER_SZ(C) \
+ ((C)->chdr & SZ_MASK)
+
+typedef union {char c[8]; long l; double d;} Unit_t;
+
+typedef struct Carrier_t_ Carrier_t;
+struct Carrier_t_ {
+ Uint chdr;
+ Carrier_t *next;
+ Carrier_t *prev;
+};
+
+typedef struct {
+ Carrier_t *first;
+ Carrier_t *last;
+} CarrierList_t;
+
+typedef Uint Block_t;
+typedef Uint FreeBlkFtr_t;
+
+typedef struct {
+ Uint giga_no;
+ Uint no;
+} CallCounter_t;
+
+typedef struct {
+ Uint no;
+ Uint size;
+} StatValues_t;
+
+typedef struct {
+ StatValues_t curr_mseg;
+ StatValues_t curr_sys_alloc;
+ StatValues_t max;
+ StatValues_t max_ever;
+ struct {
+ StatValues_t curr;
+ StatValues_t max;
+ StatValues_t max_ever;
+ } blocks;
+} CarriersStats_t;
+
+struct Allctr_t_ {
+
+ /* Allocator name prefix */
+ char * name_prefix;
+
+ /* Allocator number */
+ ErtsAlcType_t alloc_no;
+
+ /* Alloc, realloc and free names as atoms */
+ struct {
+ Eterm alloc;
+ Eterm realloc;
+ Eterm free;
+ } name;
+
+ /* Version string */
+ char * vsn_str;
+
+ /* Options */
+ int t;
+ int ramv;
+ Uint sbc_threshold;
+ Uint sbc_move_threshold;
+ Uint mbc_move_threshold;
+ Uint main_carrier_size;
+ Uint max_mseg_sbcs;
+ Uint max_mseg_mbcs;
+ Uint largest_mbc_size;
+ Uint smallest_mbc_size;
+ Uint mbc_growth_stages;
+#if HAVE_ERTS_MSEG
+ ErtsMsegOpt_t mseg_opt;
+#endif
+
+ /* */
+ Uint mbc_header_size;
+ Uint sbc_header_size;
+ Uint min_mbc_size;
+ Uint min_mbc_first_free_size;
+ Uint min_block_size;
+
+ /* Carriers */
+ CarrierList_t mbc_list;
+ CarrierList_t sbc_list;
+
+ /* Main carrier (if there is one) */
+ Carrier_t * main_carrier;
+
+ /* Callback functions (first 4 are mandatory) */
+ Block_t * (*get_free_block) (Allctr_t *, Uint,
+ Block_t *, Uint);
+ void (*link_free_block) (Allctr_t *, Block_t *);
+ void (*unlink_free_block) (Allctr_t *, Block_t *);
+ Eterm (*info_options) (Allctr_t *, char *, int *,
+ void *, Uint **, Uint *);
+
+ Uint (*get_next_mbc_size) (Allctr_t *);
+ void (*creating_mbc) (Allctr_t *, Carrier_t *);
+ void (*destroying_mbc) (Allctr_t *, Carrier_t *);
+ void (*init_atoms) (void);
+
+#ifdef ERTS_ALLOC_UTIL_HARD_DEBUG
+ void (*check_block) (Allctr_t *, Block_t *, int);
+ void (*check_mbc) (Allctr_t *, Carrier_t *);
+#endif
+
+#ifdef USE_THREADS
+ /* Mutex for this allocator */
+ erts_mtx_t mutex;
+ int thread_safe;
+ struct {
+ Allctr_t *prev;
+ Allctr_t *next;
+ } ts_list;
+#endif
+
+ int atoms_initialized;
+
+ int stopped;
+
+ /* Some statistics ... */
+ struct {
+ CallCounter_t this_alloc;
+ CallCounter_t this_free;
+ CallCounter_t this_realloc;
+ CallCounter_t mseg_alloc;
+ CallCounter_t mseg_dealloc;
+ CallCounter_t mseg_realloc;
+ CallCounter_t sys_alloc;
+ CallCounter_t sys_free;
+ CallCounter_t sys_realloc;
+ } calls;
+
+ CarriersStats_t sbcs;
+ CarriersStats_t mbcs;
+
+#ifdef DEBUG
+#ifdef USE_THREADS
+ struct {
+ int saved_tid;
+ erts_tid_t tid;
+ } debug;
+#endif
+#endif
+};
+
+int erts_alcu_start(Allctr_t *, AllctrInit_t *);
+void erts_alcu_stop(Allctr_t *);
+
+unsigned long erts_alcu_test(unsigned long, unsigned long, unsigned long);
+
+
+
+#endif /* #if defined(GET_ERL_ALLOC_UTIL_IMPL)
+ && !defined(ERL_ALLOC_UTIL_IMPL__) */
+