在linux内核中为struct数组分配内存,并获得奇怪的输出od structs id
我在linux内核中编写了一个程序,它应该为5个简单的结构分配内存,每个结构都有唯一的id,所以我在构造函数中使用static int并增加它,最后我只是将消息打印到缓冲区。当我看到缓冲区时,我得到了一个奇怪的结果,因为id的值,比如0、64、128、192、256,我很惊讶,因为我认为我会看到0、1、2、3、4这样的值。为什么我会得到这样的结果?有什么不对劲吗 输出: [2653.505140]示例结构id:0在linux内核中为struct数组分配内存,并获得奇怪的输出od structs id,c,linux,struct,kernel,C,Linux,Struct,Kernel,我在linux内核中编写了一个程序,它应该为5个简单的结构分配内存,每个结构都有唯一的id,所以我在构造函数中使用static int并增加它,最后我只是将消息打印到缓冲区。当我看到缓冲区时,我得到了一个奇怪的结果,因为id的值,比如0、64、128、192、256,我很惊讶,因为我认为我会看到0、1、2、3、4这样的值。为什么我会得到这样的结果?有什么不对劲吗 输出: [2653.505140]示例结构id:0 [2653.505143]示例字符串字段内容:测试 [2653.526565]示例
[2653.505143]示例字符串字段内容:测试
[2653.526565]示例结构id:64
[2653.526568]示例字符串字段内容:测试
[2653.526623]示例结构id:128
[2653.526625]示例字符串字段内容:测试
[2653.550439]示例结构id:192
[2653.550443]示例字符串字段内容:测试
[2653.550513]示例结构id:256
[2653.550514]示例字符串字段内容:测试
这是我的代码:
#include<linux/module.h>
#include<linux/slab.h>
#include<linux/string.h>
static struct example_struct {
unsigned int id;
char example_string[10];
} *example_struct_pointer[5];
static struct kmem_cache *example_cachep[5];
static void example_constructor(void *argument)
{
static unsigned int id;
static char test_string[] = "Test";
struct example_struct *example = (struct example_struct *)argument;
example->id = id;
strcpy(example->example_string,test_string);
id++;
}
void print_example_struct(struct example_struct *example)
{
pr_notice("Example struct id: %d\n",example->id);
pr_notice("Example string field content: %s\n",example->example_string);
}
static int __init zad1_init(void)
{
int i;
for(i = 0; i < 5; i++){
example_cachep[i] = kmem_cache_create("example cache", sizeof(struct example_struct),0, SLAB_HWCACHE_ALIGN|SLAB_POISON|SLAB_RED_ZONE, example_constructor);
if(IS_ERR(example_cachep[i])) {
pr_alert("Error creating cache: %ld\n",PTR_ERR(example_cachep[i]));
return -ENOMEM;
}
}
for(i = 0; i < 5; i++){
example_struct_pointer[i] = (struct example_struct *) kmem_cache_alloc(example_cachep[i],GFP_KERNEL);
if(IS_ERR(example_struct_pointer[i])) {
pr_alert("Error allocating form cache: %ld\n", PTR_ERR(example_struct_pointer[i]));
kmem_cache_destroy(example_cachep[i]);
return -ENOMEM;
}
}
return 0;
}
static void __exit zad1_exit(void)
{
int i;
for(i = 0; i < 5; i++){
if(example_cachep[i]) {
if(example_struct_pointer[i]) {
print_example_struct(example_struct_pointer[i]);
kmem_cache_free(example_cachep[i],example_struct_pointer[i]);
}
kmem_cache_destroy(example_cachep[i]);
}
}
}
module_init(zad1_init);
module_exit(zad1_exit);
MODULE_LICENSE("GPL");
#包括
#包括
#包括
静态结构示例\u结构{
无符号整数id;
字符示例_字符串[10];
}*示例_结构_指针[5];
静态结构kmem_cache*示例_cachep[5];
静态void示例_构造函数(void*参数)
{
静态无符号整数id;
静态字符测试_字符串[]=“测试”;
struct example_struct*example=(struct example_struct*)参数;
示例->id=id;
strcpy(示例->示例字符串、测试字符串);
id++;
}
无效打印\u示例\u结构(结构示例\u结构*示例)
{
pr_通知(“示例结构id:%d\n”,示例->id);
请购单通知(“示例字符串字段内容:%s\n”,示例->示例字符串);
}
静态整数初始化zad1初始化(无效)
{
int i;
对于(i=0;i<5;i++){
示例缓存p[i]=kmem\u缓存创建(“示例缓存”,sizeof(struct example\u struct),0,SLAB\HWCACHE\u ALIGN,SLAB\u毒物,SLAB\u红色区域,示例构造函数);
if(IS_ERR(例如_cachep[i])){
pr_警报(“创建缓存时出错:%ld\n”,PTR_ERR(例如缓存[i]));
return-ENOMEM;
}
}
对于(i=0;i<5;i++){
示例\u结构\u指针[i]=(结构示例\u结构*)kmem\u cache\u alloc(示例\u cachep[i],GFP\u内核);
if(IS_ERR(例如结构指针[i])){
pr_警报(“分配表单缓存时出错:%ld\n”,PTR_ERR(示例结构指针[i]);
kmem_cache_destroy(示例_cachep[i]);
return-ENOMEM;
}
}
返回0;
}
静态无效\uuuu出口zad1\u出口(无效)
{
int i;
对于(i=0;i<5;i++){
if(示例_cachep[i]){
if(示例\u结构\u指针[i]){
打印示例结构(示例结构指针[i]);
kmem_cache_free(示例_cachep[i],示例_struct_pointer[i]);
}
kmem_cache_destroy(示例_cachep[i]);
}
}
}
模块初始化(zad1初始化);
模块出口(zad1出口);
模块许可证(“GPL”);
ctor
函数的kmem\u cache\u create
参数不是一般意义上的构造函数
不能保证给定的函数只会被调用一次,并且只有在从缓存请求对象时才会被调用。担保实际上是相反的():
因此,对ctor
的调用可能比从缓存请求的对象数量多得多
如果只想分配和初始化几个对象,只需定义相应的构造函数:
// Single cache can be used for allocate multiple object.
// No needs to define a cache-per-object.
static struct kmem_cache* example_cachep;
// Constructor for the object of type 'example_struct'.
static struct example_struct* create_example_object(void)
{
static unsigned int id;
struct example_struct *example = kmem_cache_alloc(example_cachep, GFP_KERNEL);
if (example != NULL)
{
example->id = id;
strcpy(example->example_string, "Test");
id++;
}
return example;
}
static int __init zad1_init(void)
{
// ...
// Create the cache.
example_cachep = kmem_cache_create("example cache", sizeof(struct example_struct),0, SLAB_HWCACHE_ALIGN|SLAB_POISON|SLAB_RED_ZONE, example_constructor);
// create several 'example' objects.
for(i = 0; i < 5; i++){
example_struct_pointer[i] = create_example_object();
if(example_struct_pointer[i] == NULL)
{
// ... Somehow process the allocation failure.
}
}
return 0;
}
//单个缓存可用于分配多个对象。
//无需为每个对象定义缓存。
静态结构kmem_cache*示例_cachep;
//类型为“example_struct”的对象的构造函数。
静态结构示例\u结构*创建\u示例\u对象(无效)
{
静态无符号整数id;
struct example\u struct*example=kmem\u cache\u alloc(example\u cachep,GFP\u内核);
如果(示例!=NULL)
{
示例->id=id;
strcpy(示例->示例字符串,“测试”);
id++;
}
返回示例;
}
静态整数初始化zad1初始化(无效)
{
// ...
//创建缓存。
示例_cachep=kmem_cache_create(“示例缓存”,sizeof(struct example_struct),0,SLAB_HWCACHE_ALIGN | SLAB_POISON | SLAB_RED_ZONE,示例_构造函数);
//创建几个“示例”对象。
对于(i=0;i<5;i++){
示例_结构_指针[i]=创建_示例_对象();
if(示例结构指针[i]==NULL)
{
//…以某种方式处理分配失败。
}
}
返回0;
}
ctor
参数仅用于初始化对象的某些字段。这样的初始化可以节省一点时间(稍微提高性能),但只有在以下两种条件都适用时才能:
usage\u count
字段,该字段在对象刚刚初始化和对象将被释放时都等于0
ctor
对于此类字段的用处在于,对于先前从同一缓存中解除分配的已分配对象,可能不会调用ctor
。也就是说,您可以通过不初始化已经具有所需值的字段来节省时间
因为不初始化单个(或多个)值只能节省一点时间,但是调用
ctor
的次数可能会超过需要的次数,因此您应该仔细测量您是否确实获得了性能,而不是失去了性能。您误解了kmem\u缓存
函数的工作原理。kmem\u cache\u create
功能
// Single cache can be used for allocate multiple object.
// No needs to define a cache-per-object.
static struct kmem_cache* example_cachep;
// Constructor for the object of type 'example_struct'.
static struct example_struct* create_example_object(void)
{
static unsigned int id;
struct example_struct *example = kmem_cache_alloc(example_cachep, GFP_KERNEL);
if (example != NULL)
{
example->id = id;
strcpy(example->example_string, "Test");
id++;
}
return example;
}
static int __init zad1_init(void)
{
// ...
// Create the cache.
example_cachep = kmem_cache_create("example cache", sizeof(struct example_struct),0, SLAB_HWCACHE_ALIGN|SLAB_POISON|SLAB_RED_ZONE, example_constructor);
// create several 'example' objects.
for(i = 0; i < 5; i++){
example_struct_pointer[i] = create_example_object();
if(example_struct_pointer[i] == NULL)
{
// ... Somehow process the allocation failure.
}
}
return 0;
}