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

📄 guialloc.c

📁 S3C44B0X在UCOSII的源码
💻 C
字号:
/***********************************************************************************************************                                                uC/GUI*                        Universal graphic software for embedded applications**                       (c) Copyright 2002, Micrium Inc., Weston, FL*                       (c) Copyright 2002, SEGGER Microcontroller Systeme GmbH**              礐/GUI is protected by international copyright laws. Knowledge of the*              source code may not be used to write a similar product. This file may*              only be used in accordance with a license and should not be redistributed*              in any way. We appreciate your understanding and fairness.*----------------------------------------------------------------------File        : GUIAlloc.CPurpose     : emWin dynamic memory management----------------------------------------------------------------------Version-Date---Author-Explanation----------------------------------------------------------------------1.00    000107 RS     First version----------------------------------------------------------------------Known problems:None.----------------------------------------------------------------------Open issues:None.----------------------------------------------------------------------Todo:Nothing.*/#include <stddef.h>           /* needed for definition of NULL */#include <string.h>           /* for memcpy, memset */#include "GUI_Protected.H"#include "GUIDebug.h"#if GUI_ALLOC_SIZE==0  #error GUI_ALLOC_SIZE needs to be > 0 when using this module#endif/*  *****************************************************************  *  *              Config defaults  *  ******************************************************************//* Permit automatic defragmentation when necessary */#ifndef GUI_ALLOC_AUTDEFRAG  #define GUI_ALLOC_AUTDEFRAG 1#endif#ifndef GUI_BLOCK_ALIGN  #define GUI_BLOCK_ALIGN 2    /* 2 means 4 bytes, 1 means 2 bytes */                              /* 1 can be used on 16-bit CPUs and                                 CPUs which do not require aligned                                 32-bit values (such as x86) */ #endif#ifndef GUI_MAXBLOCKS  #define GUI_MAXBLOCKS (2+GUI_ALLOC_SIZE/32)#endif/*  *****************************************************************  *  *              Internal types and declarations  *  ******************************************************************/#if GUI_ALLOC_SIZE <32767  #define tALLOCINT I16#else  #define tALLOCINT I32#endif#if GUI_MAXBLOCKS >= 256  #define HANDLE U16#else  #define HANDLE U8#endiftypedef struct {  tALLOCINT Off;       /* Offset of memory area */  tALLOCINT Size;      /* usable size of allocated block */  HANDLE Next;      /* next handle in linked list */  HANDLE Prev;} tBlock;/******************************************************************              Static data*******************************************************************/GUI_HEAP GUI_Heap;       /* Public for debugging only */static tBlock aBlock[GUI_MAXBLOCKS];struct {  int       NumUsedBlocks, NumFreeBlocks, NumFreeBlocksMin;        /* For statistical purposes only */  tALLOCINT NumUsedBytes,  NumFreeBytes,  NumFreeBytesMin;} GUI_ALLOC;static char   IsInitialized =0;/*  ********************************************************************  *  *                 Macros for internal use  *  *********************************************************************/#define Min(v0,v1) ((v0>v1) ? v1 : v0)#define Max(v0,v1) ((v0>v1) ? v0 : v1)#define ASSIGN_IF_LESS(v0,v1) if (v1<v0) v0=v1#define HMEM2PTR(hMem) (void*)&GUI_Heap.abHeap[aBlock[hMem].Off]/*  ********************************************************************  *  *                    Internal routines  *  *********************************************************************//*  *************************************************  *  *                 Size2LegalSize  *  *************************************************  returns: Legal allocation size*/static int Size2LegalSize(int size) {  return (size + ((1<<GUI_BLOCK_ALIGN)-1)) & ~((1<<GUI_BLOCK_ALIGN)-1);}  /*  *************************************************  *  *                 FindFreeHandle  *  *************************************************  returns: Free handle*/static GUI_HMEM FindFreeHandle(void) {  int i;  for (i=1; i< GUI_MAXBLOCKS; i++) {    if (aBlock[i].Size ==0)	  return i;  }  GUI_DEBUG_ERROROUT1("Insufficient memory handles configured (GUI_MAXBLOCKS == %d (See GUIConf.h))", GUI_MAXBLOCKS);  return GUI_HMEM_NULL;}/*  *************************************************  *  *               Find hole in heap area  *  *************************************************  returns: Offset to the memory hole (if available)           -1 if not available*/static GUI_HMEM FindHole(int Size) {  int i, iNext;  for (i=0; (iNext = aBlock[i].Next) != 0; i = iNext) {    int NumFreeBytes = aBlock[iNext].Off- (aBlock[i].Off+aBlock[i].Size);    if (NumFreeBytes>=Size)      return i;  }/* Check last block */  if (GUI_ALLOC_SIZE - (aBlock[i].Off+aBlock[i].Size) >= Size)    return i;  return -1;}/*  *************************************************  *  *             Create hole in heap area  *  *************************************************  returns: Offset to the memory hole (if available)           -1 if not available*/static GUI_HMEM CreateHole(int Size) {  int i, iNext;  int r = -1;  for (i=0; (iNext =aBlock[i].Next) !=0; i= iNext) {    int NumFreeBytes = aBlock[iNext].Off- (aBlock[i].Off+aBlock[i].Size);    if (NumFreeBytes < Size) {      int NumBytesBeforeBlock = aBlock[iNext].Off - (aBlock[i].Off+aBlock[i].Size);      if (NumBytesBeforeBlock) {        U8* pData = &GUI_Heap.abHeap[aBlock[iNext].Off];        memmove(pData-NumBytesBeforeBlock, pData, aBlock[iNext].Size);        aBlock[iNext].Off -=NumBytesBeforeBlock;      }    }  }/* Check last block */  if (GUI_ALLOC_SIZE - (aBlock[i].Off+aBlock[i].Size) >= Size)    r = i;  return r;}static void CheckInit(void) {  if (!IsInitialized)    GUI_ALLOC_Init();}/*  ********************************************************************  *  *                  Exported routines  *  *********************************************************************/void GUI_ALLOC_Init(void) {  GUI_DEBUG_LOG("\nGUI_ALLOC_Init...");  GUI_ALLOC.NumFreeBlocksMin = GUI_ALLOC.NumFreeBlocks = GUI_MAXBLOCKS-1;  GUI_ALLOC.NumFreeBytesMin  = GUI_ALLOC.NumFreeBytes  = GUI_ALLOC_SIZE;  GUI_ALLOC.NumUsedBlocks = 0;  GUI_ALLOC.NumUsedBytes = 0;  aBlock[0].Size = (1<<GUI_BLOCK_ALIGN);  /* occupy minimum for a block */  aBlock[0].Off  = 0;  aBlock[0].Next = 0;  IsInitialized =1;}static GUI_HMEM _Alloc(int size) {  GUI_HMEM hMemNew, hMemIns;  CheckInit();  size = Size2LegalSize(size);  /* Check if memory is available at all ...*/  if (size > GUI_ALLOC.NumFreeBytes) {    GUI_DEBUG_WARN1("GUI_ALLOC_Alloc: Insufficient memory configured (Trying to alloc % bytes)", size);    return 0;  }  /* Locate free handle */  if ((hMemNew = FindFreeHandle()) == 0)    return 0;  /* Locate or Create hole of sufficient size */  hMemIns = FindHole(size);  #if GUI_ALLOC_AUTDEFRAG    if (hMemIns == -1) {      hMemIns = CreateHole(size);    }  #endif/* Occupy hole */  if (hMemIns==-1) {    GUI_DEBUG_ERROROUT1("GUI_ALLOC_Alloc: Could not allocate %d bytes",size);    return 0;	}  {    int Off = aBlock[hMemIns].Off+aBlock[hMemIns].Size;    int Next = aBlock[hMemIns].Next;    aBlock[hMemNew].Size  = size;    aBlock[hMemNew].Off   = Off;    if ((aBlock[hMemNew].Next  = Next) >0) {      aBlock[Next].Prev = hMemNew;      }    aBlock[hMemNew].Prev  = hMemIns;    aBlock[hMemIns].Next  = hMemNew;  }/* Keep track of number of blocks and av. memory */  GUI_ALLOC.NumUsedBlocks++;  GUI_ALLOC.NumFreeBlocks--;  if (GUI_ALLOC.NumFreeBlocksMin > GUI_ALLOC.NumFreeBlocks) {    GUI_ALLOC.NumFreeBlocksMin = GUI_ALLOC.NumFreeBlocks;  }  GUI_ALLOC.NumUsedBytes += size;  GUI_ALLOC.NumFreeBytes -= size;  if (GUI_ALLOC.NumFreeBytesMin > GUI_ALLOC.NumFreeBytes) {    GUI_ALLOC.NumFreeBytesMin = GUI_ALLOC.NumFreeBytes;  }/* In order to be on the safe side, zeroinit ! */  memset(HMEM2PTR(hMemNew), 0, size);  return hMemNew;}GUI_HMEM GUI_ALLOC_Alloc(int size) {  GUI_HMEM hMem; /* First make sure that init has been called */  GUI_LOCK();  GUI_DEBUG_LOG2("\nGUI_ALLOC_Alloc... requesting %d, %d avail", size, GUI_ALLOC.NumFreeBytes);  hMem = _Alloc(size);  GUI_DEBUG_LOG1("\nGUI_ALLOC_Alloc : Handle", hMem);  GUI_UNLOCK();  return hMem;}void GUI_ALLOC_Free(GUI_HMEM hMem) {  int Size;  if (hMem == GUI_HMEM_NULL)  /* Note: This is not an error, it is permitted */    return;  GUI_LOCK();  GUI_DEBUG_LOG1("\nGUI_ALLOC_Free(%d)", hMem);  /* Do some error checking ... */  #if GUI_DEBUG_LEVEL>0    /* Block not allocated ? */    if (aBlock[hMem].Size==0) {      GUI_DEBUG_ERROROUT("GUI_ALLOC_Free(): Invalid hMem");      return;    }  #endif  Size = aBlock[hMem].Size;  #ifdef WIN32    memset(&GUI_Heap.abHeap[aBlock[hMem].Off], 0xcc, Size);  #endif  GUI_ALLOC.NumFreeBytes += Size;  GUI_ALLOC.NumUsedBytes -= Size;  aBlock[hMem].Size = 0;  {    int Next = aBlock[hMem].Next;    int Prev = aBlock[hMem].Prev;    aBlock[Prev].Next = Next;    if (Next)      aBlock[Next].Prev = Prev;  }    GUI_ALLOC.NumFreeBlocks++;  GUI_ALLOC.NumUsedBlocks--;  GUI_UNLOCK();}void*       GUI_ALLOC_h2p   (GUI_HMEM  hMem) {  #if GUI_DEBUG_LEVEL>0    if (!hMem) {      GUI_DEBUG_ERROROUT("\n"__FILE__ " GUI_ALLOC_h2p: illegal argument (0 handle)");      return 0;    }  #endif  return HMEM2PTR(hMem);}void GUI_ALLOC_FreePtr(GUI_HMEM *ph) {  GUI_LOCK();  GUI_ALLOC_Free(*ph);  *ph =0;  GUI_UNLOCK();}/*  ********************************************************************  *  *                  Exported info routines  *  *********************************************************************/int GUI_GetUsedMem(void) {  int NumUsedBytes=0;  int i;  GUI_LOCK();  CheckInit();  for (i=1; i; i = aBlock[i].Next) {    NumUsedBytes += aBlock[i].Size;  }  GUI_UNLOCK();  return NumUsedBytes;}int GUI_ALLOC_GetNumFreeBytes(void) {  CheckInit();  return GUI_ALLOC.NumFreeBytes;  }/*  *************************************************  *  *       GetMaxSize  *  *************************************************  Returns the biggest available blocksize  (without relocation)*/int GUI_ALLOC_GetMaxSize(void) {  int r=0;  int NumFreeBytes;  int i, iNext;  GUI_LOCK();  CheckInit();  for (i=0; (iNext =aBlock[i].Next) !=0; i= iNext) {    NumFreeBytes = aBlock[iNext].Off- (aBlock[i].Off+aBlock[i].Size);    if (NumFreeBytes > r) {      r = NumFreeBytes;    }  }/* Check last block */  NumFreeBytes = (GUI_ALLOC_SIZE - (aBlock[i].Off+aBlock[i].Size));  if (NumFreeBytes > r) {    r = NumFreeBytes;  }  GUI_UNLOCK();  return r;}

⌨️ 快捷键说明

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