⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 erl_alloc.h

📁 OTP是开放电信平台的简称
💻 H
字号:
/* ``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 via the world wide web 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. *  * The Initial Developer of the Original Code is Ericsson Utvecklings AB. * Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings * AB. All Rights Reserved.'' *  *     $Id$ */#ifndef ERL_ALLOC_H__#define ERL_ALLOC_H__#include "erl_alloc_types.h"#include "erl_alloc_util.h"#ifdef ERTS_ALC_THR_SPEC_ALLOCS#ifdef USE_THREADS#include "erl_threads.h"#endif#endif#ifdef DEBUG#  undef ERTS_ALC_WANT_INLINE#  define ERTS_ALC_WANT_INLINE 0#endif#ifndef ERTS_ALC_WANT_INLINE#  define ERTS_ALC_WANT_INLINE 1#endif#if ERTS_CAN_INLINE && ERTS_ALC_WANT_INLINE#  define ERTS_ALC_DO_INLINE 1#  define ERTS_ALC_INLINE static ERTS_INLINE#else#  define ERTS_ALC_DO_INLINE 0#  define ERTS_ALC_INLINE#endif#define ERTS_FIX_CORE_ALLOCATOR ERTS_ALC_A_LONG_LIVEDextern ErtsAlcType_t erts_fix_core_allocator_ix;typedef struct {    Uint total;    Uint used;} ErtsFixInfo;void erts_sys_alloc_init(void);void *erts_sys_alloc(ErtsAlcType_t, void *, Uint);void *erts_sys_realloc(ErtsAlcType_t, void *, void *, Uint);void erts_sys_free(ErtsAlcType_t, void *, void *);void erts_init_fix_alloc(Uint, void *(*)(Uint));Uint erts_get_fix_size(ErtsAlcType_t);void erts_set_fix_size(ErtsAlcType_t, Uint);void erts_fix_info(ErtsAlcType_t, ErtsFixInfo *);void *erts_fix_alloc(ErtsAlcType_t, void *, Uint);void *erts_fix_realloc(ErtsAlcType_t, void *, void*, Uint);void erts_fix_free(ErtsAlcType_t, void *, void*);Eterm erts_memory(int *, void *, void *, Eterm);Eterm erts_allocated_areas(int *, void *, void *);void erts_allocator_info(int, void *);Eterm erts_allocator_info_term(void *proc, Eterm which_alloc);Eterm erts_allocator_options(void *proc);void erts_alloc_init(int *argc, char **argv);#if defined(GET_ERTS_ALC_TEST) || defined(ERTS_ALC_INTERNAL__)/* Only for testing */unsigned long erts_alc_test(unsigned long,			    unsigned long,			    unsigned long,			    unsigned long);#endif#define ERTS_ALC_O_ALLOC		0#define ERTS_ALC_O_REALLOC		1#define ERTS_ALC_O_FREE			2#define ERTS_ALC_E_NOTSUP		0#define ERTS_ALC_E_NOMEM		1#define ERTS_ALC_E_NOALLCTR		2#define ERTS_ALC_MIN_LONG_LIVED_TIME	(10*60*1000)typedef struct {    int alloc_util;    int enabled;    void *extra;} ErtsAllocatorInfo_t;typedef struct {    void *	(*alloc)	(ErtsAlcType_t, void *, Uint);    void *	(*realloc)	(ErtsAlcType_t, void *, void *, Uint);    void	(*free)		(ErtsAlcType_t, void *, void *);    void *extra;} ErtsAllocatorFunctions_t;extern ErtsAllocatorFunctions_t erts_allctrs[ERTS_ALC_A_MAX+1];extern ErtsAllocatorInfo_t erts_allctrs_info[ERTS_ALC_A_MAX+1];#ifdef ERTS_ALC_THR_SPEC_ALLOCS#ifdef USE_THREADStypedef struct {    erts_tsd_key_t key;    void * (*start)(void);} ErtsAllocatorThrSpec_t;extern ErtsAllocatorThrSpec_t erts_allctr_thr_spec[ERTS_ALC_A_MAX+1];#endif#endifvoid erts_alloc_enomem(ErtsAlcType_t,Uint)		__noreturn;void erts_alloc_n_enomem(ErtsAlcType_t,Uint)		__noreturn;void erts_realloc_enomem(ErtsAlcType_t,void*,Uint)	__noreturn;void erts_realloc_n_enomem(ErtsAlcType_t,void*,Uint)	__noreturn;void erts_alc_fatal_error(int,int,ErtsAlcType_t,...)	__noreturn;/* --- DO *NOT* USE THESE DEPRECATED FUNCTIONS ---    Instead use:       */void *safe_alloc(Uint)               __deprecated; /* erts_alloc()       */void *safe_realloc(void *, Uint)     __deprecated; /* erts_realloc()     */void  sys_free(void *)               __deprecated; /* erts_free()        */void *sys_alloc(Uint )               __deprecated; /* erts_alloc_fnf()   */void *sys_realloc(void *, Uint)      __deprecated; /* erts_realloc_fnf() *//* * erts_alloc[_fnf](), erts_realloc[_fnf](), erts_free() works as * malloc(), realloc(), and free() with the following exceptions: * * * They take an extra type argument as first argument which is *   the memory type to operate on. Memory types are generated *   (as ERTS_ALC_T_[SOMETHING] defines) from the erl_alloc.types *   configuration file. * * The erts_alloc() and erts_realloc() functions terminate the *   emulator if memory cannot be obtained. The _fnf (Failure Not *   Fatal) suffixed versions return NULL if memory cannot be *   obtained. * * They may be static functions so function pointers to "the same" *   function may differ. * * IMPORTANT: Memory allocated or reallocated as type X, can only *            be reallocated or deallocated as type X. */#if !ERTS_ALC_DO_INLINEvoid *erts_alloc(ErtsAlcType_t type, Uint size);void *erts_realloc(ErtsAlcType_t type, void *ptr, Uint size);void erts_free(ErtsAlcType_t type, void *ptr);void *erts_alloc_fnf(ErtsAlcType_t type, Uint size);void *erts_realloc_fnf(ErtsAlcType_t type, void *ptr, Uint size);#endif /* #if !ERTS_ALC_DO_INLINE */#if ERTS_ALC_DO_INLINE || defined(ERTS_ALC_INTERNAL__)ERTS_ALC_INLINEvoid *erts_alloc(ErtsAlcType_t type, Uint size){    void *res;    res = (*erts_allctrs[ERTS_ALC_T2A(type)].alloc)(	ERTS_ALC_T2N(type),	erts_allctrs[ERTS_ALC_T2A(type)].extra,	size);    if (!res)	erts_alloc_n_enomem(ERTS_ALC_T2N(type), size);    return res;}ERTS_ALC_INLINEvoid *erts_realloc(ErtsAlcType_t type, void *ptr, Uint size){    void *res;    res = (*erts_allctrs[ERTS_ALC_T2A(type)].realloc)(	ERTS_ALC_T2N(type),	erts_allctrs[ERTS_ALC_T2A(type)].extra,	ptr,	size);    if (!res)	erts_realloc_n_enomem(ERTS_ALC_T2N(type), ptr, size);    return res;}ERTS_ALC_INLINEvoid erts_free(ErtsAlcType_t type, void *ptr){    (*erts_allctrs[ERTS_ALC_T2A(type)].free)(	ERTS_ALC_T2N(type),	erts_allctrs[ERTS_ALC_T2A(type)].extra,	ptr);}ERTS_ALC_INLINEvoid *erts_alloc_fnf(ErtsAlcType_t type, Uint size){    return (*erts_allctrs[ERTS_ALC_T2A(type)].alloc)(	ERTS_ALC_T2N(type),	erts_allctrs[ERTS_ALC_T2A(type)].extra,	size);}ERTS_ALC_INLINEvoid *erts_realloc_fnf(ErtsAlcType_t type, void *ptr, Uint size){    return (*erts_allctrs[ERTS_ALC_T2A(type)].realloc)(	ERTS_ALC_T2N(type),	erts_allctrs[ERTS_ALC_T2A(type)].extra,	ptr,	size);}#endif /* #if ERTS_ALC_DO_INLINE || defined(ERTS_ALC_INTERNAL__) */#define ERTS_QUALLOC_IMPL(NAME, TYPE, PASZ, ALCT)			\ERTS_QUICK_ALLOC_IMPL(NAME, TYPE, PASZ, ALCT,				\		      (void) 0, (void) 0, (void) 0)#define ERTS_SMP_QUALLOC_IMPL(NAME, TYPE, PASZ, ALCT)			\static erts_smp_spinlock_t NAME##_lck;					\ERTS_QUICK_ALLOC_IMPL(NAME, TYPE, PASZ, ALCT,				\		      erts_smp_spinlock_init(&NAME##_lck, #NAME "_alloc_lock"),\		      erts_smp_spin_lock(&NAME##_lck),			\		      erts_smp_spin_unlock(&NAME##_lck))#ifdef ERTS_SMP#define ERTS_TS_QUALLOC_IMPL(NAME, TYPE, PASZ, ALCT)			\ERTS_SMP_QUALLOC_IMPL(NAME, TYPE, PASZ, ALCT)#else /* !ERTS_SMP */#define ERTS_TS_QUALLOC_IMPL(NAME, TYPE, PASZ, ALCT)			\static erts_mtx_t NAME##_lck;						\ERTS_QUICK_ALLOC_IMPL(NAME, TYPE, PASZ, ALCT,				\		      erts_mtx_init(NAME##_lck, #NAME "_alloc_lock"),	\		      erts_mtx_lock(&NAME##_lck),			\		      erts_mtx_unlock(&NAME##_lck))#endif#define ERTS_PALLOC_IMPL(NAME, TYPE, PASZ)				\ERTS_PRE_ALLOC_IMPL(NAME, TYPE, PASZ, (void) 0, (void) 0, (void) 0)#define ERTS_SMP_PALLOC_IMPL(NAME, TYPE, PASZ)				\static erts_smp_spinlock_t NAME##_lck;					\ERTS_PRE_ALLOC_IMPL(NAME, TYPE, PASZ,					\		    erts_smp_spinlock_init(&NAME##_lck, #NAME "_alloc_lock"),\		    erts_smp_spin_lock(&NAME##_lck),			\		    erts_smp_spin_unlock(&NAME##_lck))#ifdef ERTS_SMP#define ERTS_TS_PALLOC_IMPL(NAME, TYPE, PASZ)				\ERTS_SMP_PALLOC_IMPL(NAME, TYPE, PASZ)#else /* !ERTS_SMP */#define ERTS_TS_PALLOC_IMPL(NAME, TYPE, PASZ)				\static erts_mtx_t NAME##_lck;						\ERTS_PRE_ALLOC_IMPL(NAME, TYPE, PASZ,					\		    erts_mtx_init(NAME##_lck, #NAME "_alloc_lock"),	\		    erts_mtx_lock(&NAME##_lck),				\		    erts_mtx_unlock(&NAME##_lck))#endif#define ERTS_QUICK_ALLOC_IMPL(NAME, TYPE, PASZ, ALCT, ILCK, LCK, ULCK)	\ERTS_PRE_ALLOC_IMPL(NAME##_pre, TYPE, PASZ, ILCK, LCK, ULCK)		\static void								\init_##NAME##_alloc(void)						\{									\    init_##NAME##_pre_alloc();						\}									\static ERTS_INLINE TYPE *						\NAME##_alloc(void)							\{									\    TYPE *res = NAME##_pre_alloc();					\    if (!res)								\	res = erts_alloc(ALCT, sizeof(TYPE));				\    return res;								\}									\static ERTS_INLINE void							\NAME##_free(TYPE *p)							\{									\    if (!NAME##_pre_free(p))						\	erts_free(ALCT, (void *) p);					\}#ifdef DEBUG#define ERTS_PRE_ALLOC_SIZE(SZ) 2#define ERTS_PRE_ALLOC_CLOBBER(P, T) memset((void *) (P), 0xfd, sizeof(T))#else#define ERTS_PRE_ALLOC_SIZE(SZ) ((SZ) > 1 ? (SZ) : 1)#define ERTS_PRE_ALLOC_CLOBBER(P, T)#endif#define ERTS_PRE_ALLOC_IMPL(NAME, TYPE, PASZ, ILCK, LCK, ULCK)		\union erts_qa_##NAME##__ {						\    TYPE type;								\    union erts_qa_##NAME##__ *next;					\};									\static union erts_qa_##NAME##__						\    qa_prealcd_##NAME[ERTS_PRE_ALLOC_SIZE((PASZ))];			\static union erts_qa_##NAME##__ *qa_freelist_##NAME;			\static void								\init_##NAME##_alloc(void)						\{									\    int i;								\    qa_freelist_##NAME = &qa_prealcd_##NAME[0];				\    for (i = 1; i < ERTS_PRE_ALLOC_SIZE((PASZ)); i++) {			\	ERTS_PRE_ALLOC_CLOBBER(&qa_prealcd_##NAME[i-1],			\			       union erts_qa_##NAME##__);		\	qa_prealcd_##NAME[i-1].next = &qa_prealcd_##NAME[i];		\    }									\    ERTS_PRE_ALLOC_CLOBBER(&qa_prealcd_##NAME[ERTS_PRE_ALLOC_SIZE((PASZ))-1],\			   union erts_qa_##NAME##__);			\    qa_prealcd_##NAME[ERTS_PRE_ALLOC_SIZE((PASZ))-1].next = NULL;	\    ILCK;								\}									\static ERTS_INLINE TYPE *						\NAME##_alloc(void)							\{									\    TYPE *res;								\    LCK;								\    if (!qa_freelist_##NAME)						\	res = NULL;							\    else {								\	res = &qa_freelist_##NAME->type;				\	qa_freelist_##NAME = qa_freelist_##NAME->next;			\    }									\    ULCK;								\    return res;								\}									\static ERTS_INLINE int							\NAME##_free(TYPE *p)							\{									\    union erts_qa_##NAME##__ * up;					\    up = ((union erts_qa_##NAME##__ *)					\	  (((char *) p)							\	   - ((char *) &((union erts_qa_##NAME##__ *) 0)->type)));	\    if (up > &qa_prealcd_##NAME[ERTS_PRE_ALLOC_SIZE((PASZ))-1]		\	|| up < &qa_prealcd_##NAME[0])					\	return 0;							\    else {								\	LCK;								\	ERTS_PRE_ALLOC_CLOBBER(up, union erts_qa_##NAME##__);		\	up->next = qa_freelist_##NAME;					\	qa_freelist_##NAME = up;					\	ULCK;								\	return 1;							\    }									\}#ifdef DEBUG#define ERTS_ALC_DBG_BLK_SZ(PTR) (*(((Uint *) (PTR)) - 2))#endif /* #ifdef DEBUG */#undef ERTS_ALC_INLINE#undef ERTS_ALC_ATTRIBUTES#endif /* #ifndef ERL_ALLOC_H__ */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -