erl_malloc.c
来自「OTP是开放电信平台的简称」· C语言 代码 · 共 235 行
C
235 行
/* ``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$ */#include "eidef.h"#include <stddef.h>#include <stdlib.h>#include "erl_interface.h"#include "erl_fix_alloc.h"#include "erl_malloc.h"#include "erl_internal.h"#include "erl_eterm.h"#include "ei_malloc.h"void erl_init_malloc(Erl_Heap *hp, long heap_size) { erl_init_eterm_alloc();} /* erl_init_malloc */ETERM *erl_alloc_eterm(unsigned char type){ ETERM *e; /* Use fix size allocator */ if (!(e = (ETERM *) erl_eterm_alloc())) erl_err_sys("<ERROR> erl_alloc_eterm: Failed to allocate more memory\n"); ERL_HEADER(e)->count = 0; ERL_HEADER(e)->type = type; return e;} /* erl_alloc_eterm */#define EXTERNAL 1#define INTERNAL 0#define COMPOUND 1#define NOT_COMPOUND 0static void _erl_free_term (ETERM *ep, int external, int compound);/* * Free a term, but don't deallocate it until * the reference counter triggers. */void erl_free_term(ETERM *ep){ _erl_free_term(ep, EXTERNAL, NOT_COMPOUND);} /* erl_free_term *//* * Free a term regardless of its reference * counter value. Use this when you have * built compound terms such as lists or tuples. *//* * FIXME is this true?! * Tearing down term structures no-matter-what is a horrible idea if * any term happens to be shared (with some other structure or even * with yourself). */void erl_free_compound (ETERM *ep){ _erl_free_term(ep, EXTERNAL, COMPOUND);} /* erl_free_compound *//*** The actual free'ing is done here in _erl_free_term.** It is by nature recursive, but does not recurse ** on the CDR of a list, which makes it usable for large lists.*//*** Convenience macro, called for variables and lists,** avoids deep recursions.*/#define RESTART(Eterm, External, Compound) \do { \ ETERM *sep; \ sep = (Eterm); \ external = (External); \ compound = (Compound); \ /* Clear header info */ \ ERL_TYPE(ep) = ERL_UNDEF; \ erl_eterm_free((unsigned int *) ep); \ ep = sep; \ goto restart; \} while(0)#define FREE_AND_CLEAR(ptr) \do { \ erl_free(ptr); \ (ptr) = NULL; \} while (0)static void _erl_free_term (ETERM *ep, int external, int compound){restart: if (ep == NULL) return; if (compound || ERL_NO_REF(ep)) { /* Yes, it's time to *really* free this one ! */ switch(ERL_TYPE(ep)) { case ERL_ATOM: FREE_AND_CLEAR(ERL_ATOM_PTR(ep)); break; case ERL_VARIABLE: FREE_AND_CLEAR(ERL_VAR_NAME(ep)); /* Note: It may be unbound ! */ if (ERL_VAR_VALUE(ep) != NULL) { ERL_COUNT(ERL_VAR_VALUE(ep))--; /* Cleanup and Restart with the actual value */ RESTART(ERL_VAR_VALUE(ep), INTERNAL, compound); } break; case ERL_LIST: ERL_COUNT(HEAD(ep))--; /* FIXME added cast, is this correct? */ _erl_free_term((ETERM *)HEAD(ep), INTERNAL, compound); ERL_COUNT(TAIL(ep))--; /* Clean up and walk on to CDR in list */ RESTART(TAIL(ep), INTERNAL, compound); break; case ERL_TUPLE: { int i; for (i=0; i < ERL_TUPLE_SIZE(ep); i++) if (ERL_TUPLE_ELEMENT(ep, i)) { ERL_COUNT(ERL_TUPLE_ELEMENT(ep, i))--; _erl_free_term(ERL_TUPLE_ELEMENT(ep, i), INTERNAL, compound); } FREE_AND_CLEAR(ERL_TUPLE_ELEMS(ep)); } break; case ERL_BINARY: FREE_AND_CLEAR(ERL_BIN_PTR(ep)); break; case ERL_PID: FREE_AND_CLEAR(ERL_PID_NODE(ep)); break; case ERL_PORT: FREE_AND_CLEAR(ERL_PORT_NODE(ep)); break; case ERL_REF: FREE_AND_CLEAR(ERL_REF_NODE(ep)); break; case ERL_EMPTY_LIST: case ERL_INTEGER: case ERL_SMALL_BIG: case ERL_U_SMALL_BIG: case ERL_FLOAT: break; case ERL_FUNCTION: { int i; _erl_free_term(ERL_FUN_INDEX(ep), INTERNAL, compound); _erl_free_term(ERL_FUN_UNIQ(ep), INTERNAL, compound); _erl_free_term(ERL_FUN_CREATOR(ep), INTERNAL, compound); _erl_free_term(ERL_FUN_MODULE(ep), INTERNAL, compound); if (ERL_CLOSURE(ep) != NULL) { for (i = 0; i < ERL_CLOSURE_SIZE(ep); i++) _erl_free_term(ERL_CLOSURE_ELEMENT(ep,i), INTERNAL, compound); } } break; } /* switch */ /* Clear header info for those cases where we are done */ ERL_TYPE(ep) = ERL_UNDEF; erl_eterm_free(ep); } else if (external) { ERL_COUNT(ep)--; external = INTERNAL; goto restart; }} /* _erl_free_term */#undef RESTART#undef FREE_AND_CLEARvoid erl_free_array(ETERM **arr, int size){ int i; for (i=0; i<size; i++) erl_free_term(arr[i]);} /* erl_free_array */void* erl_malloc (long size){ void *res; if ((res = ei_malloc(size)) == NULL) erl_err_sys("<ERROR> erl_malloc: Failed to allocate more memory"); return res;}void* erl_realloc(void* orig, long size){ void *res; if ((res = ei_realloc(orig, size)) == NULL) erl_err_sys("<ERROR> erl_realloc: Failed to allocate more memory"); return res;}void erl_free (void *ptr){ ei_free(ptr);}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?