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

📄 mem.c

📁 Bycore是一个嵌入式操作系统内核。Bycore包括内存管理、任务管理、中断管理、任务互斥、同步与通信管理等功能。Bycore全部由C语言完成
💻 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 + -