Chinaunix首页 | 论坛 | 博客
  • 博客访问: 15498890
  • 博文数量: 2005
  • 博客积分: 11986
  • 博客等级: 上将
  • 技术积分: 22535
  • 用 户 组: 普通用户
  • 注册时间: 2007-05-17 13:56
文章分类

全部博文(2005)

文章存档

2014年(2)

2013年(2)

2012年(16)

2011年(66)

2010年(368)

2009年(743)

2008年(491)

2007年(317)

分类: C/C++

2007-07-09 16:57:27

 

浅析μC/GUI-v3.98之GUI_ALLOC_AllocZero()内存申请转句柄hWin函数

文章来源:http://gliethttp.cublog.cn

-------------------------------------------------------------------------------------
1.GUI_ALLOC_AllocZero()
gui/core/GUI_ALLOC_AllocZero.c
GUI_HMEM GUI_ALLOC_AllocZero(GUI_ALLOC_DATATYPE Size) {
  GUI_HMEM hMem;
  GUI_LOCK();
  GUI_DEBUG_LOG2("\nGUI_ALLOC_Alloc... requesting %d, %d avail", Size, GUI_ALLOC_GetMaxSize());
  hMem = GUI_ALLOC_AllocNoInit(Size);                      //申请size大小的内存空间,返回对该内存空间的目录索引
  if (hMem) {
    GUI_MEMSET((U8*)GUI_ALLOC_h2p(hMem), 0, Size);         //填充0

  }
  GUI_UNLOCK();
  return hMem;
}
-------------------------------------------------------------------------------------
2.GUI_ALLOC_AllocNoInit()函数
gui/core/GUIAlloc.c
GUI_HMEM GUI_ALLOC_AllocNoInit(GUI_ALLOC_DATATYPE Size) {
  GUI_HMEM hMem;
  if (Size == 0) {
    return (GUI_HMEM)0;
  }
  GUI_LOCK();
  GUI_DEBUG_LOG2("\nGUI_ALLOC_AllocNoInit... requesting %d, %d avail", Size, GUI_ALLOC.NumFreeBytes);
  hMem = _Alloc(Size);                                     //申请size大小的内存空间,返回对该内存空间的目录索引
  GUI_DEBUG_LOG1("\nGUI_ALLOC_AllocNoInit : Handle", hMem);
  GUI_UNLOCK();
  return hMem;
}
-------------------------------------------------------------------------------------
3._Alloc()函数
gui/core/GUIAlloc.c
static GUI_HMEM _Alloc(GUI_ALLOC_DATATYPE size) {
  GUI_HMEM hMemNew, hMemIns;
  _CheckInit();                                            //检测GUI_ALLOC内存监控变量单元是否初始化,若未初始化,初始化之
  size = _Size2LegalSize(size);                            //处理器字节对齐,可以是2字节,4字节
  /* Check if memory is available at all ...*/
  if (size > _GetNumFreeBytes()) {                         //返回空闲字节数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) {                //2007-07-09 gliethttp申请内存空间的目录索引
    return 0;
  }
  /* Locate or Create hole of sufficient size */
  hMemIns = _FindHole(size);                               //查找紧邻的两个已用单元之间是否有size大小夹缝空间

  #if GUI_ALLOC_AUTDEFRAG
    if (hMemIns == -1) {
      if (_LockCnt == 0) {
        hMemIns = _CreateHole(size);                       //没有夹缝空间,创建全新的内存单元,同时整理内存碎片
      }
    }
  #endif
  /* Occupy hole */
  if (hMemIns==-1) {
    GUI_DEBUG_ERROROUT1("GUI_ALLOC_Alloc: Could not allocate %d bytes",size);
    return 0;
    }
  {
    GUI_ALLOC_DATATYPE Off = aBlock[hMemIns].Off + aBlock[hMemIns].Size;//空闲内存起始地址偏移量Off
    int Next = aBlock[hMemIns].Next;                                    //如果hMemIns是夹缝空间,那么将新单元hMemNew插入到hMemIns和hMemIns.Next之间
    aBlock[hMemNew].Size = size;
    aBlock[hMemNew].Off = Off;
    if ((aBlock[hMemNew].Next = Next) >0) {
      aBlock[Next].Prev = hMemNew;                         //如果hMemIns是夹缝空间,完善双向链表
    }
    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;
  }
  return hMemNew;                                          //返回申请到的内存空间的目录索引
}
-------------------------------------------------------------------------------------
4._FindFreeHandle()函数
gui/core/GUIAlloc.c
static GUI_HMEM _FindFreeHandle(void) {
  int i;
  for (i = _FirstFreeHandle; i < GUI_MAXBLOCKS; i++) {
    if (aBlock[i].Size == 0) {
      _FirstFreeHandle = i;                                //申请内存空间的目录索引,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;
}
-------------------------------------------------------------------------------------
4._FindHole()函数
gui/core/GUIAlloc.c
static GUI_HMEM _FindHole(GUI_ALLOC_DATATYPE Size) {
  int i, iNext;
  for (i=0; (iNext = aBlock[i].Next) != 0; i = iNext) {
    GUI_ALLOC_DATATYPE NumFreeBytes = aBlock[iNext].Off- (aBlock[i].Off+aBlock[i].Size);
    if (NumFreeBytes>=Size) {                              //查找紧邻的两个已用单元之间是否有size大小空间
      return i;
    }
  }
  /* Check last block */
  if (GUI_ALLOC_SIZE - (aBlock[i].Off+aBlock[i].Size) >= Size) {
    return i;
  }
  return -1;                                               //无
}
-------------------------------------------------------------------------------------
4._CreateHole()函数
gui/core/GUIAlloc.c
static GUI_HMEM _CreateHole(GUI_ALLOC_DATATYPE Size) {
  int i, iNext;
  int r = -1;
  for (i=0; (iNext =aBlock[i].Next) !=0; i= iNext) {       //创建全新的内存单元,同时整理内存碎片
    GUI_ALLOC_DATATYPE NumFreeBytes = aBlock[iNext].Off- (aBlock[i].Off+aBlock[i].Size);
    if (NumFreeBytes < Size) {
      GUI_ALLOC_DATATYPE 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;                                                 //aBlock[r].Off+aBlock[r].Size即空闲内存的起始地址
  }
  return r;
}

阅读(6618) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~