携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第2天,点击查看活动详情
内核中高级语法和特殊数据结构
attribute GNU C 的一大特色就是__attribute__ 机制。attribute 可以设置函数属性(Function Attribute )、变量属性(Variable Attribute )和类型属性(Type Attribute )。
#书写特征是:前后都有两个下划线,并切后面会紧跟一对原括弧,括弧里面是相应的__attribute__ 参数。
__attribute__
#语法格式为:
__attribute__ ((attribute-list))
示例代码:
Learning_set/Language/c++/c at master · EVAcacia/Learning_set · GitHub
static void __attribute__((constructor)) do_qemu_init_ ## function(void) \
{ \
register_module_init(function, type); \
}
如果函数被设定为constructor属性,则该函数会在main()函数执行之前被自动的执行;
若函数被设定为destructor属性,则该函数会在main()函数执行之后或者exit()被调用后被自动的执行。
解析:
1.暂定
__read_mostly的使用 定义:
#define __read_mostly attribute((section(".data..read_mostly"))) 1 使用:
static unsigned int d_hash_shift __read_mostly;
1 也就是说被__read_mostly 形容的数据别放入到了段. data.read_mostly 中
那这个段的作用是什么呢?
定义到这个段的数据,再 linux 内核被加载时,数据会自动被存放到 cache 中,以提高整个系统的执行效率。另一方面,如果所在的平台没有 cache,或者有 cache,但是并没有提供存放数据的接口 (也就是不允许人工放置数据在 cache 中),这样定义为__ead_mostly 类型的数据将不能存放在 linux 内核中,甚至也不能被加载到系统内存去执行,将造成 linux 内核启动失败。
当不能存放数据时,解决方法:
1,修改 inclue/asm/cache.h 中的__read_mostly 定义为空的,如:__
__define __read_mostly
2,修改 arch/mips/kernel/vmlinux.s,将. data.read_mostly 段的位置定义到实际内存空间中去。
c语言的可变参数
int func(int, ... )
{
.
.
.
}
int main()
{
func(2, 2, 3);
func(3, 2, 3, 4);
}
使用 int 参数和 va_start 宏来初始化 va_list 变量为一个参数列表。
使用 va_arg 宏和 va_list 变量来访问参数列表中的每个项。
使用宏 va_end 来清理赋予 va_list 变量的内存。
#include <stdio.h>
#include <stdarg.h>
double average(int num,...)
{
va_list valist;
double sum = 0.0;
int i;
/* 为 num 个参数初始化 valist */
va_start(valist, num);
/* 访问所有赋给 valist 的参数 */
for (i = 0; i < num; i++)
{
sum += va_arg(valist, int);
}
/* 清理为 valist 保留的内存 */
va_end(valist);
return sum/num;
}
int main()
{
printf("Average of 2, 3, 4, 5 = %f\n", average(4, 2,3,4,5));
printf("Average of 5, 10, 15 = %f\n", average(3, 5,10,15));
}