乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      lwip之內(nèi)存管理

       立志德美 2019-07-17

      1、C library內(nèi)存管理

      c庫自帶內(nèi)存分配和釋放函數(shù)malloc和free:
      void *malloc(long NumBytes):該函數(shù)分配了NumBytes個字節(jié),并返回了指向這塊內(nèi)存的指針。如果分配失敗,則返回一個空指針(NULL)。

      void free(void *FirstByte): 該函數(shù)是將之前用malloc分配的空間還給程序或者是操作系統(tǒng),也就是釋放了這塊內(nèi)存,讓它重新得到自由。

      2、lwip內(nèi)存池管理

      1)相關(guān)宏定義

      (a)內(nèi)存策略宏開關(guān)
      //使用C library中函數(shù)malloc和free實現(xiàn)內(nèi)存堆分配和釋放
      MEM_LIBC_MALLOC==1 
      
      //使用lwip內(nèi)存堆分配策略實現(xiàn)內(nèi)存池分配
      MEMP_MEM_MALLOC==1
      
      //使用lwip內(nèi)存池分配策略實現(xiàn)內(nèi)存堆的分配,需額外定義新的內(nèi)存池
      MEM_USE_POOLS==1
      MEMP_USE_CUSTOM_POOLS==1
      MEM_USE_POOLS_TRY_BIGGER_POOL==1
      
      //新內(nèi)存池定義格式如下:
       /* Define three pools with sizes 256, 512, and 1512 bytes
       * LWIP_MALLOC_MEMPOOL_START
       * LWIP_MALLOC_MEMPOOL(20, 256)
       * LWIP_MALLOC_MEMPOOL(10, 512)
       * LWIP_MALLOC_MEMPOOL(5, 1512)
       * LWIP_MALLOC_MEMPOOL_END
       */
      (b)內(nèi)存字節(jié)、地址對齊宏定義
      #define MEM_ALIGNMENT    4   /*cpu alignment*/
      
      //(e.g. LWIP_MEM_ALIGN_SIZE(3) and  LWIP_MEM_ALIGN_SIZE(4) will both yield 4 for MEM_ALIGNMENT == 4)
      #define LWIP_MEM_ALIGN_SIZE(size) 
        (((size) + MEM_ALIGNMENT - 1) & ~(MEM_ALIGNMENT-1))
      
      // (e.g. if buffer is u8_t[] and actual data will be u32_t*)
      #define LWIP_MEM_ALIGN_BUFFER(size) 
        (((size) + MEM_ALIGNMENT - 1))
      
      // ADDR % MEM_ALIGNMENT == 0
      #define LWIP_MEM_ALIGN(addr) 
       ((void *)(((mem_ptr_t)(addr) + MEM_ALIGNMENT - 1) &
                           ~(mem_ptr_t)(MEM_ALIGNMENT-1)))
      (c)內(nèi)存池全局變量聲明
      #define MEMP_SIZE           0
      #define MEMP_ALIGN_SIZE(x) (LWIP_MEM_ALIGN_SIZE(x))
      
      /** This array holds the first free element of each pool. Elements form a linked list. */
      static struct memp *memp_tab[MEMP_MAX];
      
      //不同類型內(nèi)存池的大小
      static const u16_t memp_sizes[MEMP_MAX] = {
      #define LWIP_MEMPOOL(name,num,size,desc)    LWIP_MEM_ALIGN_SIZE(size),
      #include "lwip/memp_std.h"
      };
      
      //不同類型內(nèi)存池的數(shù)量
      static const u16_t memp_num[MEMP_MAX] = {
      #define LWIP_MEMPOOL(name,num,size,desc)  (num),
      #include "lwip/memp_std.h"
      };
      
      //調(diào)試專用描述符
      static const char *memp_desc[MEMP_MAX] = {
      #define LWIP_MEMPOOL(name,num,size,desc)  (desc),
      #include "lwip/memp_std.h"
      };
      
      //定義內(nèi)存池數(shù)組,開辟靜態(tài)內(nèi)存空間
      static u8_t memp_memory[MEM_ALIGNMENT - 1 
      #define LWIP_MEMPOOL(name,num,size,desc) + ( (num) * (MEMP_SIZE + MEMP_ALIGN_SIZE(size) ) )
      #include "lwip/memp_std.h"
      (d)未用到功能的宏設(shè)置
      #define MEMP_STATS                      0
      #define MEMP_SEPARATE_POOLS             0
      #define MEMP_OVERFLOW_CHECK             0
      #define MEMP_SANITY_CHECK               0

      2)內(nèi)存池實現(xiàn)

      (a)結(jié)構(gòu)體聲明
      //內(nèi)存池類型枚舉
      typedef enum {
      #define LWIP_MEMPOOL(name,num,size,desc)  MEMP_##name,
      #include "lwip/memp_std.h"
        MEMP_MAX
      } memp_t;
      
      //內(nèi)存池操作結(jié)構(gòu)體
      struct memp {
        struct memp *next;
      };
      (b)各種類型內(nèi)存池數(shù)量及其大小的定義(部分)
      LWIP_MEMPOOL(RAW_PCB,MEMP_NUM_RAW_PCB, 
                    sizeof(struct raw_pcb), "RAW_PCB")
      LWIP_MEMPOOL(UDP_PCB,  MEMP_NUM_UDP_PCB,  
                    sizeof(struct udp_pcb), "UDP_PCB")
      LWIP_MEMPOOL(TCP_PCB,MEMP_NUM_TCP_PCB,  
                    sizeof(struct tcp_pcb), "TCP_PCB")
      
      #define LWIP_PBUF_MEMPOOL(name, num, payload, desc) LWIP_MEMPOOL(name, num, MEMP_ALIGN_SIZE(sizeof(struct pbuf)) + MEMP_ALIGN_SIZE(payload)), desc)
      
      LWIP_PBUF_MEMPOOL(PBUF, MEMP_NUM_PBUF,  0, "PBUF_REF/ROM")
      LWIP_PBUF_MEMPOOL(PBUF_POOL,PBUF_POOL_SIZE,
                        PBUF_POOL_BUFSIZE,"PBUF_POOL")
      (c)內(nèi)存池初始化memp_init

      初始化內(nèi)存池結(jié)構(gòu)示意圖
      memp memory

      void memp_init(void)
      {
        struct memp *memp;
        u16_t i, j;
      
        memp = (struct memp *)LWIP_MEM_ALIGN(memp_memory);
      
        /* for every pool: */
        for (i = 0; i < MEMP_MAX; ++i) {
          memp_tab[i] = NULL;
      
          /* create a linked list of memp elements */
          for (j = 0; j < memp_num[i]; ++j) {
            memp->next = memp_tab[i];
            memp_tab[i] = memp;
            memp = (struct memp *)(void *)((u8_t *)memp + MEMP_SIZE + memp_sizes[i]);
          }
        }
      }
      (d)內(nèi)存池分配memp_malloc
      void *memp_malloc(memp_t type)
      
      {
        struct memp *memp;
        SYS_ARCH_DECL_PROTECT(old_level);
        SYS_ARCH_PROTECT(old_level);
      
        memp = memp_tab[type];
      
      //申請一個type類型的內(nèi)存池
        if (memp != NULL) {
          memp_tab[type] = memp->next;
          memp = (struct memp*)(void *)((u8_t*)memp + MEMP_SIZE);
        } 
        else {
          MEMP_STATS_INC(err, type);
        }
      
        SYS_ARCH_UNPROTECT(old_level);
        return memp;
      }
      (e)內(nèi)存池釋放memp_free
      void memp_free(memp_t type, void *mem)
      {
        struct memp *memp;
        SYS_ARCH_DECL_PROTECT(old_level);
      
        if (mem == NULL) {
          return;
        }
      
        memp = (struct memp *)(void *)((u8_t*)mem - MEMP_SIZE);
      
        SYS_ARCH_PROTECT(old_level);
        MEMP_STATS_DEC(used, type); 
      
        //切換表頭
        memp->next = memp_tab[type]; 
        memp_tab[type] = memp;
      
        SYS_ARCH_UNPROTECT(old_level);
      }

      3、lwip內(nèi)存堆管理

      1)、miscellaneous聲明

      //內(nèi)存堆管理結(jié)構(gòu)體
      struct mem {
        mem_size_t next;  //字節(jié)索引號
        mem_size_t prev;
        u8_t used;
      };
      
      //mem_size_t聲明
      #if MEM_SIZE > 64000L
      typedef u32_t mem_size_t;
      #define MEM_SIZE_F U32_F
      #else
      typedef u16_t mem_size_t;
      #define MEM_SIZE_F U16_F
      #endif /* MEM_SIZE > 64000 */
      
      //自定義最小、最大申請內(nèi)存大小
      #define MIN_SIZE             12
      #define MEM_SIZE             (10*1024)
      
      //對齊聲明
      #define MIN_SIZE_ALIGNED     LWIP_MEM_ALIGN_SIZE(MIN_SIZE)
      #define SIZEOF_STRUCT_MEM 
                         LWIP_MEM_ALIGN_SIZE(sizeof(struct mem))
      #define MEM_SIZE_ALIGNED     LWIP_MEM_ALIGN_SIZE(MEM_SIZE)
      
      //全局變量聲明,靜態(tài)數(shù)組聲明
      u8_t ram_heap[MEM_SIZE_ALIGNED +
                 (2*SIZEOF_STRUCT_MEM) + MEM_ALIGNMENT];
      #define LWIP_RAM_HEAP_POINTER ram_heap
      
      static u8_t *ram;
      static struct mem *ram_end;
      static struct mem *lfree;

      2)、內(nèi)存堆初始化mem_init

      void mem_init(void)
      {
        struct mem *mem;
        /* align the heap */
       // LWIP_RAM_HEAP_POINTER <=> ram_heap
        ram = (u8_t *)LWIP_MEM_ALIGN(LWIP_RAM_HEAP_POINTER);
      
        /* initialize the start of the heap */
        mem = (struct mem *)(void *)ram;
        mem->next = MEM_SIZE_ALIGNED;
        mem->prev = 0;
        mem->used = 0;
      
        /* initialize the end of the heap */
        ram_end = (struct mem *)(void *)&ram[MEM_SIZE_ALIGNED];
        ram_end->used = 1;
        ram_end->next = MEM_SIZE_ALIGNED;
        ram_end->prev = MEM_SIZE_ALIGNED;
      
        //initialize the lowest-free pointer to the start of the heap 
        lfree = (struct mem *)(void *)ram;
      
        MEM_STATS_AVAIL(avail, MEM_SIZE_ALIGNED);
      
        if(sys_mutex_new(&mem_mutex) != ERR_OK) {
          LWIP_ASSERT("failed to create mem_mutex", 0);
        }
      }

      初始化及分配2個內(nèi)存塊的結(jié)構(gòu)示意圖如:
      mem

      3)、內(nèi)存堆分配mem_malloc

      void *mem_malloc(mem_size_t size)
      {
        mem_size_t ptr, ptr2;
        struct mem *mem, *mem2;
      
        LWIP_MEM_ALLOC_DECL_PROTECT();
      
        if (size == 0) {
          return NULL;
        }
      
        /* Expand the size of the allocated memory region so that we can adjust for alignment. */
        size = LWIP_MEM_ALIGN_SIZE(size);
      //檢查申請空間的大小
        if(size < MIN_SIZE_ALIGNED) {
          size = MIN_SIZE_ALIGNED;
        }
      
        if (size > MEM_SIZE_ALIGNED) {
          return NULL;
        }
      
        sys_mutex_lock(&mem_mutex);
        LWIP_MEM_ALLOC_PROTECT();
      
        for (ptr = (mem_size_t)((u8_t *)lfree - ram); 
                ptr < MEM_SIZE_ALIGNED - size;
                ptr = ((struct mem *)(void *)&ram[ptr])->next)
        {
      
            mem = (struct mem *)(void *)&ram[ptr];
      
            // 判斷該空閑內(nèi)存塊未用且容量是否大于size
            if ((!mem->used) &&
                (mem->next - (ptr + SIZEOF_STRUCT_MEM)) >= size) {
      
           //判斷該空閑塊容量是否大于size + MIN_SIZE_ALIGNED
              if (mem->next - (ptr + SIZEOF_STRUCT_MEM) >= (size + SIZEOF_STRUCT_MEM + MIN_SIZE_ALIGNED)) {
      
        //申請size大小內(nèi)存塊后,組織剩下的空閑內(nèi)存
                ptr2 = ptr + SIZEOF_STRUCT_MEM + size;
                /* create mem2 struct */
                mem2 = (struct mem *)(void *)&ram[ptr2];
                mem2->used = 0;
                mem2->next = mem->next;
                mem2->prev = ptr;
      
       // and insert it between mem and mem->next 
                mem->next = ptr2;
                mem->used = 1;
      
                if (mem2->next != MEM_SIZE_ALIGNED) {
                  ((struct mem *)(void *)&ram[mem2->next])->prev = ptr2;
                }
      MEM_STATS_INC_USED(used, (size + SIZEOF_STRUCT_MEM));
              } else {
      
       //空閑塊容量大于size,小于size + MIN_SIZE_ALIGNE時,直接占用該內(nèi)存塊
                mem->used = 1;
       MEM_STATS_INC_USED(used, mem->next - 
                         (mem_size_t)((u8_t *)mem - ram));
              }
      
        //移動lfree指針       
      if (mem == lfree) {
                struct mem *cur = lfree;
      
      // Find next free block after mem and update lowest free pointer 
                while (cur->used && cur != ram_end) {
                  cur = (struct mem *)(void *)&ram[cur->next];
                }
                lfree = cur;
              }
              LWIP_MEM_ALLOC_UNPROTECT();
              sys_mutex_unlock(&mem_mutex);
      
              return (u8_t *)mem + SIZEOF_STRUCT_MEM;
            }
          }
      
        MEM_STATS_INC(err);
        LWIP_MEM_ALLOC_UNPROTECT();
        sys_mutex_unlock(&mem_mutex);
        return NULL;
      }

      多次分配內(nèi)存堆后的結(jié)構(gòu)示意圖
      ram

      4)、內(nèi)存堆釋放mem_free

      void mem_free(void *rmem)
      {
        struct mem *mem;
        LWIP_MEM_FREE_DECL_PROTECT();
      
        if (rmem == NULL) {
          return;
        }
      
        if ((u8_t *)rmem < (u8_t *)ram || (u8_t *)rmem >= (u8_t *)ram_end) {
          SYS_ARCH_DECL_PROTECT(lev);
          /* protect mem stats from concurrent access */
          SYS_ARCH_PROTECT(lev);
          MEM_STATS_INC(illegal);
          SYS_ARCH_UNPROTECT(lev);
          return;
        }
      
       /* protect the heap from concurrent access */
      
        /* Get the corresponding struct mem ... */
        mem = (struct mem *)(void *)((u8_t *)rmem - 
               SIZEOF_STRUCT_MEM);
        mem->used = 0;
      
        if (mem < lfree) {
          /* the newly freed struct is now the lowest */
          lfree = mem;
        }
      
        MEM_STATS_DEC_USED(used, mem->next - (mem_size_t)(((u8_t *)mem - ram)));
      
        //finally, see if prev or next are free also 
        // 合并相鄰空閑塊
        plug_holes(mem);
      
        LWIP_MEM_FREE_UNPROTECT();
      }

      合并相鄰空閑塊函數(shù)plug_holes

      static void plug_holes(struct mem *mem)
      {
        struct mem *nmem;
        struct mem *pmem;
      
        //檢測釋放內(nèi)存塊指向的下一個內(nèi)存塊
        nmem = (struct mem *)(void *)&ram[mem->next];
        if (mem != nmem && nmem->used == 0 &&
             (u8_t *)nmem != (u8_t *)ram_end) {
      
          if (lfree == nmem) {
            lfree = mem;
          }
          mem->next = nmem->next;
          ((struct mem *)(void *)&ram[nmem->next])->prev = (mem_size_t)((u8_t *)mem - ram);
        }
      
       //檢測釋放內(nèi)存塊指向的上一個內(nèi)存塊
        pmem = (struct mem *)(void *)&ram[mem->prev];
        if (pmem != mem && pmem->used == 0) {
      
          if (lfree == mem) {
            lfree = pmem;
          }
          pmem->next = mem->next;
          ((struct mem *)(void *)&ram[mem->next])->prev =  (mem_size_t)((u8_t *)pmem - ram);
        }
      }

        本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多