erl_fix_alloc.c

来自「OTP是开放电信平台的简称」· C语言 代码 · 共 193 行

C
193
字号
/* ``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$ *//* * Function: General purpose Memory allocator for fixed block  *    size objects. This allocater is at least an order of  *    magnitude faster than malloc(). */#include "eidef.h"#include <stdio.h>#include <stdlib.h>#include <string.h>#include "ei_locking.h"#include "erl_interface.h"#include "erl_error.h"#include "erl_malloc.h"#include "erl_fix_alloc.h"#include "erl_eterm.h"#define WIPE_CHAR ((char)0xaa) /* 10101010 *//* the freelist is a singly linked list of these *//* i.e. the user structure and a link pointer */struct fix_block {  ETERM term;  struct fix_block *next;  int free;};/* this is a struct just to keep namespace pollution low on VxWorks */struct eterm_stateinfo {  struct fix_block *freelist;  unsigned long freed;  unsigned long allocated;#ifdef _REENTRANT  ei_mutex_t *lock;#endif /* _REENTRANT */};/* FIXME problem for threaded ? */static struct eterm_stateinfo *erl_eterm_state=NULL;int erl_init_eterm_alloc (void){#if defined(PURIFY) && defined (DEBUG)    fprintf(stderr,"erl_fix_alloc() compiled for Purify - using \"real\" malloc()");#endif      erl_eterm_state = malloc(sizeof(*erl_eterm_state));    if (erl_eterm_state == NULL) goto err1;    erl_eterm_state->freelist = NULL;    erl_eterm_state->freed = 0;    erl_eterm_state->allocated = 0;#ifdef _REENTRANT    erl_eterm_state->lock = ei_mutex_create();        if (erl_eterm_state->lock == NULL) goto err2;#endif /* _REENTRANT */    return 1;    /* Error cleanup */#ifdef _REENTRANT err2:    /* FIXME ENOMEM is not what went wrong... */    free(erl_eterm_state);#endif /* _REENTRANT */ err1:    erl_errno = ENOMEM;    return 0;}/* get an eterm, from the freelist if possible or from malloc() */void *erl_eterm_alloc (void){#ifdef PURIFY    ETERM *p;      if ((p = malloc(sizeof(*p)))) {	memset(p, WIPE_CHAR, sizeof(*p));    }    return p;#else    struct fix_block *b;#ifdef _REENTRANT    ei_mutex_lock(erl_eterm_state->lock, 0);#endif /* _REENTRANT */    /* try to pop block from head of freelist */    if ((b = erl_eterm_state->freelist) != NULL) {	erl_eterm_state->freelist = b->next;	erl_eterm_state->freed--;          } else if ((b = malloc(sizeof(*b))) == NULL) {	erl_errno = ENOMEM;    }    erl_eterm_state->allocated++;    b->free = 0;    b->next = NULL;#ifdef _REENTRANT    ei_mutex_unlock(erl_eterm_state->lock);#endif /* _REENTRANT */    return (void *) &b->term;#endif /* !PURIFY */}/* free an eterm back to the freelist */void erl_eterm_free(void *p){#ifdef PURIFY  if (p) {      memset(p, WIPE_CHAR, sizeof(ETERM));  }  free(p);#else  struct fix_block *b = p;    if (b) {      if (b->free) {#ifdef DEBUG	  fprintf(stderr,"erl_eterm_free: attempt to free already freed block %p\n",b);#endif	  return;      }#ifdef _REENTRANT      ei_mutex_lock(erl_eterm_state->lock,0);#endif /* _REENTRANT */      b->free = 1;      b->next = erl_eterm_state->freelist;      erl_eterm_state->freelist = b;      erl_eterm_state->freed++;      erl_eterm_state->allocated--;#ifdef _REENTRANT      ei_mutex_unlock(erl_eterm_state->lock);#endif /* _REENTRANT */  }#endif /* !PURIFY */}/* really free the freelist */void erl_eterm_release (void){#if !defined(PURIFY)    struct fix_block *b;#ifdef _REENTRANT    ei_mutex_lock(erl_eterm_state->lock,0);#endif /* _REENTRANT */    {	while (erl_eterm_state->freelist != NULL) {	    b = erl_eterm_state->freelist;	    erl_eterm_state->freelist = b->next;	    free(b);	    erl_eterm_state->freed--;	}    }#ifdef _REENTRANT    ei_mutex_unlock(erl_eterm_state->lock);#endif /* _REENTRANT */#endif /* !PURIFY */}void erl_eterm_statistics (unsigned long *allocd, unsigned long *freed){  if (allocd) *allocd = erl_eterm_state->allocated;  if (freed) *freed = erl_eterm_state->freed;  return;}/* * Local Variables: * compile-command: "cd ..; ERL_TOP=/clearcase/otp/erts make -k" * End: */

⌨️ 快捷键说明

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