📄 memory.c
字号:
/****************************************************************************** * FREXX PROGRAMMING LANGUAGE * ****************************************************************************** memory.c Memory functions handling all allocating and freeing. *****************************************************************************//************************************************************************ * * * fpl.library - A shared library interpreting script langauge. * * Copyright (C) 1992-1997 FrexxWare * * Author: Daniel Stenberg * * * * This program is free software; you may redistribute for non * * commercial purposes only. Commercial programs must have a written * * permission from the author to use FPL. FPL is *NOT* public domain! * * Any provided source code is only for reference and for assurance * * that users should be able to compile FPL on any operating system * * he/she wants to use it in! * * * * You may not change, resource, patch files or in any way reverse * * engineer anything in the FPL package. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * * * Daniel Stenberg * * Ankdammsgatan 36, 4tr * * S-171 43 Solna * * Sweden * * * * FidoNet 2:201/328 email:dast@sth.frontec.se * * * ************************************************************************/#ifdef UNIX#include <sys/types.h>#elif defined(AMIGA)#include <exec/types.h>#include <exec/memory.h>#include <proto/exec.h>#endif#include <stdio.h>#include <stdlib.h>#include <stddef.h>#include "script.h"#include "memory.h"#include "debug.h"static void REGARGS LinkMemory(struct Data *, struct MemInfo *, uchar);static void REGARGS UnLinkMemory(struct Data *, struct MemInfo *, uchar);#ifdef DEBUGextern long mem;extern long maxmem;long malloc_count=0;long Mmalloc_count=0;long free_mem=0;long max_free_mem=0;#endif/**********************************************************************
*
* Malloc();
*
* Allocate memory for real.
*
******/
void ASM *Malloc(AREG(0) struct Data *scr, DREG(0) long size, DREG(1) uchar type
#ifdef DEBUGPARAMETERS1
DEBUGPARAMETERS1
#endif
)
{
uchar *alloc;
#ifdef DEBUG
struct MemInfo *meminfo;
size+=MEMORY_COOKIE; /* add extra bytes after the block! */
#endif
alloc=(uchar *)scr->Alloc(size+sizeof(struct MemInfo), scr->userdata);
if(!alloc) {
/* If the first alloc failed, flush caches and retry! */
FlushFree(scr);
alloc=(uchar *)scr->Alloc(size+sizeof(struct MemInfo),
scr->userdata);
if(!alloc)
return(NULL);
}
((struct MemInfo *)alloc)->size=size | (type * ALLOCBIT);
/* size = size | (type * 1<<31) */
LinkMemory(scr, (struct MemInfo *)alloc, type);
#ifdef DEBUGPARAMETERS2
meminfo=(struct MemInfo *)alloc;
meminfo->line=line;
meminfo->source=source; /* the two debugparameters */
#endif
#ifdef DEBUG
#if PRE_COOKIE>0
/* Fill the pre_cookie with junk too! */
memset((void *)meminfo->dummy, 0xbb,
sizeof(struct MemInfo)-offsetof(struct MemInfo, dummy));
#endif
#if MEMORY_COOKIE>0
memset((uchar *)meminfo + sizeof(struct MemInfo) + size-MEMORY_COOKIE,
0xbb, MEMORY_COOKIE);
#endif
Mmalloc_count++;
malloc_count++;
mem+=size+sizeof(struct MemInfo);
if(mem>maxmem)
maxmem=mem;
#endif
{static long total=0; total+=size; printf("\rMalloc %d", total)}
return (void *) ((uchar *)alloc+sizeof(struct MemInfo));
}
/********************************************************************** * * MallocCycle(); * * Get memory to a MALLOC_DYNAMIC alloc. The memory can be taken from the * memory cache if any is available. * ******/void *MallocCycle(struct Data *scr, long size#ifdef DEBUGPARAMETERS2DEBUGPARAMETERS2#endif){#if MEMORY_QUEUE>0 if(size<256) { register struct FreeBlock *pnt; size>>=4; if(pnt=scr->blox[size]) { scr->blox[size]=pnt->next; scr->blockcount[size]--;#ifdef DEBUGPARAMETERS2 pnt->mem.line=line; pnt->mem.source=source; /* the two debugparameters */#endif#ifdef DEBUG Mmalloc_count++; free_mem-=(((struct MemInfo *)pnt)->size&SIZEBITS)+ sizeof(struct MemInfo); CheckMem(scr, (uchar *)pnt+sizeof(struct MemInfo));#endif return (void *)((uchar *)pnt+sizeof(struct MemInfo)); } else size=(size<<4)+15; }#endif#ifdef DEBUGPARAMETERS2 return Malloc(scr, size, MALLOC_DYNAMIC, source, line);#else return Malloc(scr, size, MALLOC_DYNAMIC);#endif}/********************************************************************** * * DefaultAlloc(); * * THis function allocates memory from the system. Replaceable with the * tag FPLTAG_INTERNAL_ALLOC. * ******/void ASM *DefaultAlloc(DREG(0) long size, AREG(0) void *userdata){#ifdef AMIGA return (void *)AllocMem(size, MEMF_ANY);#elif defined(UNIX) return (void *)malloc(size);#endif}/********************************************************************** * * DefaultDealloc(); * * This functions does nothing but returns allocated memory to the system. * It can be replaced by a user function specified with the tag * FPLTAG_INTERNAL_DEALLOC. * ******/ void ASM DefaultDealloc(AREG(1) void *point, DREG(0) long size, AREG(0) void *userdata){#ifdef AMIGA FreeMem(point, size);#elif UNIX free(point);#endif}/********************************************************************** * * LinkMemory(); * * Adds the specifed memory area to the certain memory type list. * *****/static void REGARGSLinkMemory(struct Data *scr, struct MemInfo *point, uchar type){ point->prev=scr->MallocKey[type]; /* previous */ point->next=NULL; /* next */ if(scr->MallocKey[type]) point->prev->next=point; scr->MallocKey[type] = (void *)point;}/********************************************************************** * * UnLinkMemory(); * * Deletes the specifed memory area from the certain memory type list. * *****/static void REGARGSUnLinkMemory(struct Data *scr, struct MemInfo *point, uchar type){ if(scr->MallocKey[type]==point) { /* if this is the last Malloc, set `last' to `prev' */ scr->MallocKey[type]=point->prev; if(scr->MallocKey[type]) scr->MallocKey[type]->next=NULL; } else { /* point the previous' `next' to our `next', and our next `previous' to our `previous'. Unlink us from the chain */ if(point->prev) /* only if we aren't the _first_ Malloc() ! */ point->prev->next=point->next; if(point->next) /* only if there is a next! */ point->next->prev=point->prev; }}/********************************************************************** * * FreeCycle(); * * Free the MALLOC_DYNAMIC allocated memory to the memory cache, or if * that is full, free for real. * * In this routine we do not have to bitwise and SIZEBITS since the ALLOCBIT * is never set when this is called! * ******/void REGARGS FreeCycle(struct Data *scr, void *ptr){ struct MemInfo *point=(struct MemInfo *)((uchar *)ptr-sizeof(struct MemInfo)); /* `point' points to the MemInfo structure */#if defined(DEBUG) && defined(UNIX) if(point->size&ALLOCBIT) { fprintf(stderr, "*WARNING* Illegal free() of %d bytes!\n", point->size&SIZEBITS); }#endif#ifdef DEBUG CheckMem(scr, ptr);#endif#if MEMORY_QUEUE>0 if(point->size<256+MEMORY_COOKIE) { register long size=point->size-MEMORY_COOKIE>>4; if(scr->blockcount[size]<MEMORY_QUEUE_SIZE) {#ifdef DEBUG memset(ptr, 0xaa, point->size-MEMORY_COOKIE); free_mem+=point->size+sizeof(struct MemInfo); if(free_mem>max_free_mem) max_free_mem=free_mem;#endif ((struct FreeBlock *)point)->next=scr->blox[size]; scr->blox[size]=(struct FreeBlock *)point; scr->blockcount[size]++; return; } }#endif Free(scr, ptr, MALLOC_DYNAMIC);}/********************************************************************** * * Free(); * * Free a allocated memory area of a certain type. The freed memory * area gets freed `for real'. * *****/void ASM Free(AREG(0) struct Data *scr, AREG(1) void *ptr, DREG(0) uchar type){ struct MemInfo *point=(struct MemInfo *)((uchar *)ptr-sizeof(struct MemInfo)); /* `point' points to the MemInfo structure: */#ifdef DEBUG CheckMem(scr, ptr);#endif UnLinkMemory(scr, point, type);#ifdef DEBUG mem-=(point->size&SIZEBITS)+sizeof(struct MemInfo);#endif scr->Dealloc(point, (point->size&SIZEBITS)+sizeof(struct MemInfo), scr->userdata);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -