炫意html5
最早CSS3和HTML5移动技术网站之一

内存管理 – Linux内核API __krealloc

__krealloc函数功能描述:__krealloc( )函数的功能与krealloc( )函数的功能基本一致,都是重新分配内存,且不改变原地址空间中的内容。

__krealloc文件包含

#include<linux/slab.h>

__krealloc函数定义

在内核源码中的位置:linux-3.19.3/mm/slab_common.c

函数定义格式:

void * __krealloc(const void * p, size_t new_size, gfp_t f lags)

__krealloc输入参数说明

  • p:是需要重新分配的原内存空间的起始地址。
  • new_size:是重新分配内存所需要的字节数。
  • flags:是分配模式,其取值及含义可参考关于kmalloc( )函数的分析。

__krealloc返回参数说明

返回值为重新分配的内存的起始地址,如果分配不成功则返回NULL。

注:如果参数p为NULL,则__krealloc( )函数的功能与kmalloc( )函数一致,参考krealloc( )函数的分析。

__krealloc实例解析

编写测试文件:__krealloc.c

头文件及全局变量声明如下:

#include <linux/string.h>
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/module.h>
MODULE_LICENSE("GPL");
static int __init __krealloc_init(void);
static void __exit __krealloc_exit(void);
struct page * pages = NULL;
#define new_size   26

模块初始化函数:

int __init __krealloc_init(void)
{
pages = alloc_pages( GFP_KERNEL, 0 ); //分配一个物理页,pages为指向该页的指针
if(! pages)
{
printk("alloc failed! \n");
return -ENOMEM;
}
else
{
char * temp = (char *)pages;
char x;
*temp = 'a';
int i = 0;
for(; i < new_size; i ++)           //为分配的页前new_size个字节进行赋值
{
x = *temp;
temp ++;
*temp = x+1;
}
// 调用函数,重新分配内pages为起始地址的前new_size个字节的内容不改变
char * addr = __krealloc( pages, new_size, GFP_KERNEL);
printk("addr = 0x%lx\n", (unsigned long)addr);        //输出所拷贝的目标起始地址
printk("*addr = %c\n", *addr);                      //输出第一个字符
printk("*addr+4 = %c\n", *(addr+4));                //输出第五个字符
i = 0 ; temp = addr;
for(; i < new_size; i ++, temp ++)                    //输出新内存中的内容
printk("%c", *temp);
}
return 0;
}

模块退出函数:

void __exit __krealloc_exit(void)
{
if(pages)
{
__free_pages(pages,0);             //释放由alloc_pages( )所分配的页。
printk("\n__free_pages succeed! \n");
}
printk("exit ok! \n");
}

模块初始化及退出函数调用:

module_init(__krealloc_init);
module_exit(__krealloc_exit);

实例运行结果及分析:

首先编译模块,执行命令insmod __krealloc.ko插入模块,然后执行命令dmesg -c,会出现如图所示的结果。

Linux内核API __krealloc

执行命令rmmod __krealloc.ko卸载模块,执行命令dmesg -c,会出现如图所示的结果。

Linux内核API __krealloc

结果分析:

测试程序中调用了内核函数alloc_pages( )和__free_pages( )进行分配和释放页的操作,其具体功能参考本教程中关于它们的分析。

在本测试程序中,首先分配一个物理页作为原内存空间,然后将其new_size字节(这里取new_size为26)空间填充字符值,填充完后依次为abcd…xyz。之后调用__krealloc( )函数,参数值依次为pages、new_size、GFP_KERNEL,由字符型指针addr接收返回值。输出addr的值以及addr、addr+4的内容进行测试,输出信息中下面部分为一些警告信息。由输出信息可知addr = 0xffff8800a447500; *addr = a; *(addr + 4) = e;最后再输出新内存空间new_size字节的内容(这里通过循环实现),输出值为abcd…xyz,这也说明重新分配内存空间后保留了原地址空间的内容。最后由__free_pages( )函数释放原内存空间pages。

__krealloc( )与krealloc( )两个函数实现相同的功能,而二者的差别仅在于__krealloc( )函数不会释放原来的内存空间,即当参数p不为NULL而参数new_size为0时,它也不会释放参数p所指向的内存空间,这一点与krealloc( )函数是不同的。

炫意HTML5 » 内存管理 – Linux内核API __krealloc

Java基础教程Android基础教程