灵活使用 C 语言中的宏定义
admin
2024-05-13 08:20:54
0

最近在看内核中 qspinlock相关的代码,发现了一些有意思的实现,尤其是在 kernel/locking/qspinlock.c文件的最后几行,通过 #include "qspinlock.c"语句又把这个 C文件的内容包含了进来,但前提是在 #include之前把某些关键的宏定义改了,这就使得在处理新包含进来的文件内容时,能够得到与上面第一次处理时不一样的结果,这在很大程度上复用了代码。

下面通过一个简化版的例子来展示上述实现的细节:
首先定义 file.c文件,它的实现类似于上述 kernel/locking/qspinlock.c文件:

#ifndef _GEN_PV_LOCK_SLOWPATH#include 
#include 
#include "file.h"static void __pv_init_node(void)
{printf("dummy\n");
}#define pv_enabled()        false#define pv_init_node        __pv_init_node#ifdef CONFIG_PARAVIRT_SPINLOCKS
#define queued_spin_lock_slowpath   native_queued_spin_lock_slowpath
#endif#endif /* _GEN_PV_LOCK_SLOWPATH */EXPORT_SYMBOL(queued_spin_lock_slowpath);
void queued_spin_lock_slowpath(void)
{if (pv_enabled()) {printf("pv enabled\n");} else {printf("pv not enabled\n");}pv_init_node();printf("symbol of this function: %s\n", SYMBOL_NAME(queued_spin_lock_slowpath));
}#if !defined(_GEN_PV_LOCK_SLOWPATH) && defined(CONFIG_PARAVIRT_SPINLOCKS)
#define _GEN_PV_LOCK_SLOWPATH#undef  pv_enabled
#define pv_enabled()    true#undef pv_init_node
void pv_init_node(void)
{printf("not dummy\n");
}#undef queued_spin_lock_slowpath
#define queued_spin_lock_slowpath   __pv_queued_spin_lock_slowpath#include "file.c"#endif

再定义与之配套的 file.h文件

#ifndef _FILE_H_
#define _FILE_H_#define SYMBOL_NAME(name) __SYMBOL_NAME(name)
#define __SYMBOL_NAME(name) __sym_##name#define DECLARE_SYMBOL(name) char *SYMBOL_NAME(name)#define EXTERN_SYMBOL(name) extern DECLARE_SYMBOL(name)#define __EXPORT_SYMBOL(name) \DECLARE_SYMBOL(name) = #name#define EXPORT_SYMBOL(name) __EXPORT_SYMBOL(name)#endif

最后定义 main.c文件

#include 
#include "file.h"#ifdef CONFIG_PARAVIRT_SPINLOCKS
EXTERN_SYMBOL(native_queued_spin_lock_slowpath);
EXTERN_SYMBOL(__pv_queued_spin_lock_slowpath);
#else
EXTERN_SYMBOL(queued_spin_lock_slowpath);
#endifvoid test(void)
{
#ifdef CONFIG_PARAVIRT_SPINLOCKSnative_queued_spin_lock_slowpath();printf("=========================================================\n");__pv_queued_spin_lock_slowpath();
#elsequeued_spin_lock_slowpath();
#endif
}int main(void)
{test();return 0;
}

下面通过 CONFIG_PARAVIRT_SPINLOCKS宏来展示两种不同的用法。

如果不定义 CONFIG_PARAVIRT_SPINLOCKS宏,相当于 queued_spin_lock_slowpath()只有一种实现: 即native_queued_spin_lock_slowpath()
而如果定义了 CONFIG_PARAVIRT_SPINLOCKS宏,相当于 queued_spin_lock_slowpath()有两种实现:即native_queued_spin_lock_slowpath()__pv_queued_spin_lock_slowpath()

用法一:不定义 CONFIG_PARAVIRT_SPINLOCKS
运行结果如下所示:

$ gcc -o main main.c file.c -I./ 
$ ./main 
pv not enabled
dummy
symbol of this function: queued_spin_lock_slowpath

用法二:定义CONFIG_PARAVIRT_SPINLOCKS
运行结果如下所示:

$ gcc -o main main.c file.c -I./ -DCONFIG_PARAVIRT_SPINLOCKS
$ ./main 
pv not enabled
dummy
symbol of this function: native_queued_spin_lock_slowpath
=========================================================
pv enabled
not dummy
symbol of this function: __pv_queued_spin_lock_slowpath

相关内容

热门资讯

linux入门---制作进度条 了解缓冲区 我们首先来看看下面的操作: 我们首先创建了一个文件并在这个文件里面添加了...
C++ 机房预约系统(六):学... 8、 学生模块 8.1 学生子菜单、登录和注销 实现步骤: 在Student.cpp的...
JAVA多线程知识整理 Java多线程基础 线程的创建和启动 继承Thread类来创建并启动 自定义Thread类的子类&#...
【洛谷 P1090】[NOIP... [NOIP2004 提高组] 合并果子 / [USACO06NOV] Fence Repair G ...
国民技术LPUART介绍 低功耗通用异步接收器(LPUART) 简介 低功耗通用异步收发器...
城乡供水一体化平台-助力乡村振... 城乡供水一体化管理系统建设方案 城乡供水一体化管理系统是运用云计算、大数据等信息化手段࿰...
程序的循环结构和random库...   第三个参数就是步长     引入文件时记得指明字符格式,否则读入不了 ...
中国版ChatGPT在哪些方面... 目录 一、中国巨大的市场需求 二、中国企业加速创新 三、中国的人工智能发展 四、企业愿景的推进 五、...
报名开启 | 共赴一场 Flu... 2023 年 1 月 25 日,Flutter Forward 大会在肯尼亚首都内罗毕...
汇编00-MASM 和 Vis... Qt源码解析 索引 汇编逆向--- MASM 和 Visual Studio入门 前提知识ÿ...
【简陋Web应用3】实现人脸比... 文章目录🍉 前情提要🌷 效果演示🥝 实现过程1. u...
前缀和与对数器与二分法 1. 前缀和 假设有一个数组,我们想大量频繁的去访问L到R这个区间的和,...
windows安装JDK步骤 一、 下载JDK安装包 下载地址:https://www.oracle.com/jav...
分治法实现合并排序(归并排序)... 🎊【数据结构与算法】专题正在持续更新中,各种数据结构的创建原理与运用✨...
在linux上安装配置node... 目录前言1,关于nodejs2,配置环境变量3,总结 前言...
Linux学习之端口、网络协议... 端口:设备与外界通讯交流的出口 网络协议:   网络协议是指计算机通信网...
Linux内核进程管理并发同步... 并发同步并发 是指在某一时间段内能够处理多个任务的能力,而 并行 是指同一时间能够处理...
opencv学习-HOG LO... 目录1. HOG(Histogram of Oriented Gradients,方向梯度直方图)1...
EEG微状态的功能意义 导读大脑的瞬时全局功能状态反映在其电场结构上。聚类分析方法一致地提取了四种头表面脑电场结构ÿ...
【Unity 手写PBR】Bu... 写在前面 前期积累: GAMES101作业7提高-实现微表面模型你需要了解的知识 【技...