📄 mem.c
字号:
/** * mem.c - Memory management. * * Copyright (C) 2008 ZhangHu * All rights reserved. * E-MAIL: anmnmnly@gmail.com * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * 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. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */#include "include/types.h"#include "include/list.h"#include "include/core.h"#include "include/mem.h"#include "include/irq.h"static struct free_struct free_area[MEM_PAGE_LIST];static page_t *mem; /* Pointer to start of memory *//** * initmem - Initialize memory. * @return: * * @notes: All memory space are free at start time. * and all space organized as one free block. */void initmem(void) { uword_t i; uword_t index = 1; page_t *page; for(i = 0; i < MEM_PAGE_LIST; i++) { free_area[i].free_link.next = &free_area[i].free_link; free_area[i].free_link.prev = &free_area[i].free_link; free_area[i].size = index * MEM_PAGE_SIZE; index *= 2; } page = ((page_t*)MEM_START_ADDR); mem = page; page->free_link.prev = &page->free_link; page->free_link.next = &page->free_link; page->mem_up = NULL; page->mem_down = NULL; page->size = MEM_SIZE; page->status = MEM_FREE; add_node_list_rear(&free_area[MEM_PAGE_LIST - 1].free_link, &page->free_link);}/** * allocate - Assign a size of 'Size' space for application. * @return: The start address if successful, ohterwise NULL. * * @notes: This function is the main routine for assignment memory. * however, applications do not called it directly. */void *allocate(uword_t Size) { list_t *plist; page_t *page; page_t *pleft; uword_t i; uword_t flag; uword_t tmp_size; page = NULL; flag = FALSE; tmp_size = Size + sizeof(page_t); /* Four-byte alignment */ if(tmp_size & 0x03) { tmp_size >>= 0x2; tmp_size += 0x1; tmp_size <<= 0x02; } /* Find a free block */ for(i = 0; i < MEM_PAGE_LIST; i++) { if(free_area[i].size < tmp_size || (free_area[i].free_link.next == &free_area[i].free_link)) { continue; } else { plist = free_area[i].free_link.next; do { page = mac_find_entry(plist, page_t, free_link); if(page->size >= tmp_size) { flag = TRUE; del_node_list(&free_area[i].free_link, plist); break; } else { plist = plist->next; } } while(plist != free_area[i].free_link.next); } if(flag == TRUE) { break; } } /* Not found a free block space */ if(flag != TRUE) { return NULL; } /* Don't need split */ if(page->size - tmp_size <= MEM_PAGE_LIMIT) { page->status = MEM_ALLOC; return (page + 1); } /* Divide this block space into two block, the one assigned to application, the other reserved */ pleft = (page_t*)((char_t*)page + tmp_size); pleft->size = page->size - tmp_size; pleft->status = MEM_FREE; pleft->mem_up = page; pleft->mem_down = page->mem_down; if(page->mem_down != NULL) { page->mem_down->mem_up = pleft; } page->status = MEM_ALLOC; page->mem_down = pleft; page->size = tmp_size; /* inserting the new free memory block to free_arer list */ for(i = 0; i < MEM_PAGE_LIST; i++) { if(free_area[i].size >= pleft->size) { add_node_list_rear(&free_area[i].free_link, &pleft->free_link); break; } } return (page + 1);}/** * free - Reclaiming a block space. * @return: * * @notes: This function is the main routine for reclaim memory. * however, applications do not called it directly. */void free(void *pfree) { uword_t i; page_t *page; page_t *up; page_t *down; /* get the page_t of reclaiming block */ page = (((page_t*)(pfree)) - 1); if(page->status != MEM_ALLOC) { return ; } page->status = MEM_FREE; up = page->mem_up; down = page->mem_down; /* combination with block that is free, and under of reclaiming block */ if(down != NULL && down->status == MEM_FREE) { for(i = 0; i < MEM_PAGE_LIST; i++) { if(free_area[i].size >= down->size) { del_node_list(&free_area[i].free_link, &down->free_link); break; } } page->size += down->size; down->size = 0; down->status = 0; down->mem_up = NULL; page->mem_down = down->mem_down; if(down->mem_down != NULL) { down->mem_down->mem_up = page; down->mem_down = NULL; } } /* combination with block that is free, and above of reclaiming block */ if(up != NULL && up->status == MEM_FREE) { for(i = 0; i < MEM_PAGE_LIST; i++) { if(free_area[i].size >= up->size) { del_node_list(&free_area[i].free_link, &up->free_link); break; } } up->size += page->size; page->size = 0; page->status = 0; page->mem_up = NULL; up->mem_down = page->mem_down; if(page->mem_down != NULL) { page->mem_down->mem_up = up; page->mem_down = NULL; } page = up; } /* inserting the new free memory block to free_arer list */ for(i = 0; i < MEM_PAGE_LIST; i++) { if(free_area[i].size >= page->size) { add_node_list_rear(&free_area[i].free_link, &page->free_link); break; } }}/** * kmalloc - Assign a size of 'Size' space for application. * The function is same as 'allocate()' * @return: The start address if successful, ohterwise NULL. * * @notes: This function designed for applications. * so, applications shoule call it for assignment memory. */void *kmalloc(uword_t Size) { void *p; mac_disable_irq(); p = allocate(Size); mac_enable_irq(); return p;}/** * kfree - Reclaiming a block space. the funtion is same as 'free()'. * @return: * * @notes: This function designed for applications. * so, applications shoule call it for Reclaiming memory. */void kfree(void *pfree) { mac_disable_irq(); free(pfree); mac_enable_irq();}/** * kmemset - Set all member of a buffer to 'ch'. * @buffer: Pointer to a buffer. * @ch: The value. * @count: The length of buffer. * @return: * * @notes: */void kmemset(void *buffer, char_t ch, uword_t count) { char_t *p; p = (char_t*)buffer; while(count--) { *p++ = ch; }}/** * kgetmemlist - Get the start address of memory. * @return: Start address of memory. * * @notes: */page_t *kgetmemlist(void) { return mem;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -