参考:Linux内核同步机制之(二):Per-CPU变量

    CPU私有变量(per-CPU变量)

    动态PCPU变量

setup_per_cpu_areas()初始化per-cpu数据。

static void __init setup_per_cpu_areas(void)
{
unsigned long size, i;
char *ptr;
unsigned long nr_possible_cpus = num_possible_cpus(); /* Copy section for each CPU (we discard the original) */
size = ALIGN(PERCPU_ENOUGH_ROOM, PAGE_SIZE);
ptr = alloc_bootmem_pages(size * nr_possible_cpus); for_each_possible_cpu(i) {
__per_cpu_offset[i] = ptr - __per_cpu_start;
memcpy(ptr, __per_cpu_start, __per_cpu_end - __per_cpu_start);
ptr += size;
}
}

下面的三个变量在vmlinux.lds中定义

        __per_cpu_load = .;
__per_cpu_start = .;
*(.data.percpu.page_aligned)
*(.data.percpu)
*(.data.percpu.shared_aligned)
__per_cpu_end = .;

在init/main.c中定义如下变量

unsigned long __per_cpu_offset[NR_CPUS] __read_mostly;

EXPORT_SYMBOL(__per_cpu_offset);

PERCPU_ENOUGH_ROOM是为每个cpu分配的副本空间大小,其中__per_cpu_end-__per_cpu_start为静态分配的percpu变量空间,

PERCPU_MODULE_RESERVE=8K位动态分配的percpu变量空间。

#define PERCPU_ENOUGH_ROOM                        \
ALIGN(__per_cpu_end - __per_cpu_start, SMP_CACHE_BYTES) + PERCPU_MODULE_RESERVE #define PERCPU_MODULE_RESERVE (8 << 10)

percpu变量静态声明

#define DEFINE_PER_CPU(type, name)         DEFINE_PER_CPU_SECTION(type, name, "")

#define DEFINE_PER_CPU_SECTION(type, name, section)            \
__attribute__((__section__(PER_CPU_BASE_SECTION section))) \
PER_CPU_ATTRIBUTES PER_CPU_DEF_ATTRIBUTES \
__typeof__(type) per_cpu__##name #define PER_CPU_BASE_SECTION ".data.percpu"

由于静态变量的特殊性,没有头文件声明percpu变量,用DEFINE_PER_CPU宏定义的变量想在其它C文件中使用,需要使用DECLARE_PER_CPU宏声明

#define DECLARE_PER_CPU(type, name)                    \
DECLARE_PER_CPU_SECTION(type, name, "") #define DECLARE_PER_CPU_SECTION(type, name, section) \
extern \
__attribute__((__section__(PER_CPU_BASE_SECTION section))) \
PER_CPU_ATTRIBUTES __typeof__(type) per_cpu__##name

使用per_cpu宏获取静态存储的percpu变量

#define per_cpu(var, cpu) \
(*SHIFT_PERCPU_PTR(&per_cpu_var(var), per_cpu_offset(cpu))) #define per_cpu_offset(x) (__per_cpu_offset[x])
#define per_cpu_var(var) per_cpu__##var
#define SHIFT_PERCPU_PTR(__p, __offset) RELOC_HIDE((__p), (__offset)) #define RELOC_HIDE(ptr, off) \
({ unsigned long __ptr; \
__asm__ ("" : "=r"(__ptr) : ""(ptr)); \
(typeof(ptr)) (__ptr + (off)); })

percpu之静态变量的更多相关文章

  1. PHP 面向对象编程和设计模式 (2/5) - 静态变量、属性和方法及延迟绑定

    PHP高级程序设计 学习笔记 2014.06.10 Static(静态)关键字用来定义静态方法和属性,static 也可用于定义静态变量以及后期静态绑定. 1.静态变量 static variable ...

  2. [转]Android静态变量的生命周期

    原文地址:https://my.oschina.net/jerikc/blog/137207 Android是用Java开发,其静态变量的生命周期遵守Java的设计.我们知道静态变量是在类被load的 ...

  3. QT,静态变量要记得初始化

    //DbUtil.h #ifndef DBUTIL_H #define DBUTIL_H using namespace std; QString md5Encode(QString passwd); ...

  4. .NET静态变量与静态方法并发的问题

    我们知道,静态变量与静态方法都是在程序编译的时候就定义好了的,并且不会存在多个副本.所以对于静态变量来说,一旦修改了就会影响全局. 因此,静态变量是存在并发性问题的,所以当我们在操作静态变量的时候需要 ...

  5. JAVA的静态变量、静态方法、静态类

    静态变量和静态方法都属于静态对象,它与非静态对象的差别需要做个说明. (1)Java静态对象和非静态对象有什么区别? 比对如下: 静态对象                                ...

  6. 关于C#静态变量初始化问题

    关于这个静态变量,平时自己没有太认真的去认识.最近调项目的bug,让我重新认识了静态变量的特点. 其实,我们一直都在说:静态变量只在类第一次初始化的时候进行初始化,以后都不初始化. 很简单的一句话,但 ...

  7. android 尽量不要使用static静态变量

    使用静态static静态变量潜在性问题: 1.占用内存,并且内存一般不会释放: 2.在系统不够内存情况下会自动回收静态内存,这样就会引起访问全局静态错误. 3.不能将activity作为static静 ...

  8. Java代码执行顺序(静态变量,非静态变量,静态代码块,代码块,构造函数)加载顺序

    //据说这是一道阿里巴巴面试题,先以这道题为例分析下 public class Text { public static int k = 0; public static Text t1 = new ...

  9. Java---类加载机制,构造方法,静态变量,(静态)代码块,父类,变量加载顺序

    直接上代码: 代码1: public class ConstroctTest { private static ConstroctTest test = new ConstroctTest(); // ...

随机推荐

  1. NETCORE MVC模块化

    NETCORE MVC模块化 ASP.NETCORE MVC模块化编程 前言 记得上一篇博客中跟大家分享的是基于ASP.NETMVC5,实际也就是基于NETFRAMEWORK平台实现的这么一个轻量级插 ...

  2. 大都市 meg

    Description 在经济全球化浪潮的影响下,习惯于漫步在清晨的乡间小路的邮递员Blue Mary也开始骑着摩托车传递邮件了.不过,她经常回忆起以前在乡间漫步的情景. 昔日,乡下有依次编号为1.. ...

  3. 报错:Could not reserve enough space for object heap error

    windows命令行运行某个命令时出现: 解决办法: 设置开始->控制面板->系统和安全->系统->高级系统设置->环境变量->系统变量->新建: 变量名: ...

  4. VS2013使用EF6通过ADO.NET 连接mySql成功步骤

    VS2013使用EF6通过ADO.NET 连接mySql成功步骤 1.安装mysql-for-visualstudio-1.2.6(我用的目前最新版,这个一般安装VS2013就已经有了,没有的话下载一 ...

  5. Flask 学习系列(三)---Jinjia2使用过滤器

    再Jinjia2中过滤器是一种转变变量输出内容的技术.··过滤器通过管道符号“|与变量链接,并且可以通过圆括号传递参数” .举例说明: {{my_variable|default('my_variab ...

  6. 基于JAVA的设计模式之适配器模式

    适配器模式概念 适配器模式把一个类的接口变换成客户端所期待的另一个接口,从而使原本因接口不匹配而无法在一起工作的两个类能够在一起工作.比如我们突然就想看电影了,但是这个电影是AVI格式的,目前我们开发 ...

  7. intelliJ idea 激活和配置

    1. 双击打开 Intellij IDEA 桌面快捷方式图标,如下图: 2. 点击 ok 按钮,进入激活页面: 3. 他提供的三种方式激活:账号激活,激活码激活,服务器地址激活,我们选择激活码激活,去 ...

  8. 函数补充:动态参数,函数嵌套,global与nonlocal关键

    一丶动态参数 1.*args 位置参数,动态传参 def func(*food): print(food) print(func("米饭","馒头"," ...

  9. SpringBoot 封装返回类以及session 添加获取

    1.创建返回类Result public class Result<T>{ /*错误码*/ private Integer code; /*提示信息 */ private String m ...

  10. Unity的stateMachineBehaviour

    Unity5新增的StateMachineBehaviour是对状态机的内置,确实方便了很多,这里记录它的两个问题: 1.如果正在执行的状态被打断,当前状态的OnStateExit不会被执行,该问题在 ...