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

📄 fix_alloc.c

📁 OTP是开放电信平台的简称
💻 C
字号:
/* ``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$ *//* General purpose Memory allocator for fixed block size objects         *//* This allocater is at least an order of magnitude faster than malloc() */#define NOPERBLOCK 20#ifdef HAVE_CONFIG_H#  include "config.h"#endif#include "sys.h"#include "erl_vm.h"#include "global.h"#include "erl_db.h"#ifdef ERTS_ALC_N_MIN_A_FIXED_SIZE#if ERTS_ALC_MTA_FIXED_SIZE#include "erl_threads.h"#include "erl_smp.h"#  ifdef ERTS_SMP#    define FA_LOCK(FA) erts_smp_spin_lock(&(FA)->slck)#    define FA_UNLOCK(FA) erts_smp_spin_unlock(&(FA)->slck)#  else#    define FA_LOCK(FA) erts_mtx_lock(&(FA)->mtx)#    define FA_UNLOCK(FA) erts_mtx_unlock(&(FA)->mtx)#  endif#else#  define FA_LOCK(FA)#  define FA_UNLOCK(FA)#endiftypedef union {double d; long l;} align_t;typedef struct fix_alloc_block {    struct fix_alloc_block *next;    align_t mem[1];} FixAllocBlock;typedef struct fix_alloc {    Uint item_size;    void *freelist;    Uint no_free;    Uint no_blocks;    FixAllocBlock *blocks;#if ERTS_ALC_MTA_FIXED_SIZE#  ifdef ERTS_SMP    erts_smp_spinlock_t slck;#  else    erts_mtx_t mtx;#  endif#endif} FixAlloc;static void *(*core_alloc)(Uint); static Uint xblk_sz;static FixAlloc **fa;#define FA_SZ (1 + ERTS_ALC_N_MAX_A_FIXED_SIZE - ERTS_ALC_N_MIN_A_FIXED_SIZE)#define FIX_IX(N) ((N) - ERTS_ALC_N_MIN_A_FIXED_SIZE)#define FIX_POOL_SZ(I_SZ) \  ((I_SZ)*NOPERBLOCK + sizeof(FixAllocBlock) - sizeof(align_t))#if defined(DEBUG) && !ERTS_ALC_MTA_FIXED_SIZEstatic int first_time;#endifvoid erts_init_fix_alloc(Uint extra_block_size,			 void *(*alloc)(Uint)){    int i;    xblk_sz = extra_block_size;    core_alloc = alloc;    fa = (FixAlloc **) (*core_alloc)(FA_SZ * sizeof(FixAlloc *));    if (!fa)	erts_alloc_enomem(ERTS_ALC_T_UNDEF, FA_SZ * sizeof(FixAlloc *));    for (i = 0; i < FA_SZ; i++)	fa[i] = NULL;#if defined(DEBUG) && !ERTS_ALC_MTA_FIXED_SIZE    first_time = 1;#endif}Uinterts_get_fix_size(ErtsAlcType_t type){    Uint i = FIX_IX(ERTS_ALC_T2N(type));    return i < FA_SZ && fa[i] ? fa[i]->item_size : 0;}voiderts_set_fix_size(ErtsAlcType_t type, Uint size){    Uint sz;    Uint i;    FixAlloc *fs;    ErtsAlcType_t t_no = ERTS_ALC_T2N(type);    sz = xblk_sz + size;#ifdef DEBUG    ASSERT(ERTS_ALC_N_MIN_A_FIXED_SIZE <= t_no);    ASSERT(t_no <= ERTS_ALC_N_MAX_A_FIXED_SIZE);#endif    while (sz % sizeof(align_t) != 0)     /* Alignment */	sz++;    i = FIX_IX(t_no);    fs = (FixAlloc *) (*core_alloc)(sizeof(FixAlloc));    if (!fs)	erts_alloc_n_enomem(t_no, sizeof(FixAlloc));        fs->item_size = sz;    fs->no_blocks = 0;    fs->no_free = 0;    fs->blocks = NULL;    fs->freelist = NULL;    if (fa[i])	erl_exit(-1, "Attempt to overwrite existing fix size (%d)", i);    fa[i] = fs;#if ERTS_ALC_MTA_FIXED_SIZE#ifdef ERTS_SMP    erts_smp_spinlock_init_x(&fs->slck, "fix_alloc", make_small(i));#else    erts_mtx_init_x(&fs->mtx, "fix_alloc", make_small(i));#endif#endif}voiderts_fix_info(ErtsAlcType_t type, ErtsFixInfo *efip){    Uint i;    FixAlloc *f;#ifdef DEBUG    FixAllocBlock *b;    void *fp;#endif    Uint real_item_size;    ErtsAlcType_t t_no = ERTS_ALC_T2N(type);    ASSERT(ERTS_ALC_N_MIN_A_FIXED_SIZE <= t_no);    ASSERT(t_no <= ERTS_ALC_N_MAX_A_FIXED_SIZE);    i = FIX_IX(t_no);    f = fa[i];    efip->total	= sizeof(FixAlloc *);    efip->used	= 0;    if (!f)	return;    real_item_size = f->item_size - xblk_sz;    FA_LOCK(f);    efip->total += sizeof(FixAlloc);    efip->total += f->no_blocks*FIX_POOL_SZ(real_item_size);    efip->used = efip->total - f->no_free*real_item_size;#ifdef DEBUG    ASSERT(efip->total >= efip->used);    for(i = 0, b = f->blocks; b; i++, b = b->next);    ASSERT(f->no_blocks == i);    for (i = 0, fp = f->freelist; fp; i++, fp = *((void **) fp));    ASSERT(f->no_free == i);#endif    FA_UNLOCK(f);}voiderts_fix_free(ErtsAlcType_t t_no, void *extra, void* ptr){    Uint i;    FixAlloc *f;    ASSERT(ERTS_ALC_N_MIN_A_FIXED_SIZE <= t_no);    ASSERT(t_no <= ERTS_ALC_N_MAX_A_FIXED_SIZE);    i = FIX_IX(t_no);    f = fa[i];    FA_LOCK(f);    *((void **) ptr) = f->freelist;    f->freelist = ptr;    f->no_free++;    FA_UNLOCK(f);}void *erts_fix_realloc(ErtsAlcType_t t_no, void *extra, void* ptr, Uint size){    erts_alc_fatal_error(ERTS_ALC_E_NOTSUP, ERTS_ALC_O_REALLOC, t_no);    return NULL;}void *erts_fix_alloc(ErtsAlcType_t t_no, void *extra, Uint size){    void *ret;    int i;    FixAlloc *f;#if defined(DEBUG) && !ERTS_ALC_MTA_FIXED_SIZE    ASSERT(ERTS_ALC_N_MIN_A_FIXED_SIZE <= t_no);    ASSERT(t_no <= ERTS_ALC_N_MAX_A_FIXED_SIZE);    if (first_time) { /* Check that all sizes have been initialized */	int i;	for (i = 0; i < FA_SZ; i++)	    ASSERT(fa[i]);	first_time = 0;    }#endif    i = FIX_IX(t_no);    f = fa[i];    ASSERT(f);    ASSERT(f->item_size >= size);    FA_LOCK(f);    if (f->freelist == NULL) {  /* Gotta alloc some more mem */	char *ptr;	FixAllocBlock *bl;	Uint n;	FA_UNLOCK(f);	bl = (*core_alloc)(FIX_POOL_SZ(f->item_size));	if (!bl)	    return NULL;	FA_LOCK(f);	bl->next = f->blocks;  /* link in first */	f->blocks = bl;	n = NOPERBLOCK;	ptr = (char *) &f->blocks->mem[0];	while(n--) {	    *((void **) ptr) = f->freelist;	    f->freelist = (void *) ptr;	    ptr += f->item_size;	}#if !ERTS_ALC_MTA_FIXED_SIZE 	ASSERT(f->no_free == 0);#endif	f->no_free += NOPERBLOCK;	f->no_blocks++;    }    ret = f->freelist;    f->freelist = *((void **) f->freelist);    ASSERT(f->no_free > 0);    f->no_free--;    FA_UNLOCK(f);    return ret;}#endif /* #ifdef ERTS_ALC_N_MIN_A_FIXED_SIZE */

⌨️ 快捷键说明

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