当前位置: 首页 > news >正文

Ubuntu 下 nginx-1.24.0 源码分析 - ngx_atomic_cmp_set 函数

目录

修正 


执行 

./configure

 命令时,输出:

 checking for OS
 + Linux 6.8.0-52-generic x86_64
checking for C compiler ... found
 + using GNU C compiler
 + gcc version: 11.4.0 (Ubuntu 11.4.0-1ubuntu1~22.04) 

 所以当前环境是 x86_64

于是在 src\os\unix\ngx_atomic.h 中

#include "ngx_gcc_atomic_x86.h"

被包含 

src/os/unix/ngx_gcc_atomic_x86.h 中:

static ngx_inline ngx_atomic_uint_t
ngx_atomic_cmp_set(ngx_atomic_t *lock, ngx_atomic_uint_t old,ngx_atomic_uint_t set)
{u_char  res;__asm__ volatile (NGX_SMP_LOCK"    cmpxchgl  %3, %1;   ""    sete      %0;       ": "=a" (res) : "m" (*lock), "a" (old), "r" (set) : "cc", "memory");return res;
}

函数功能:

原子地比较 *lock 的值是否等于 old

若相等:将 *lock 设置为 set,并返回 1(成功)

若不相等:不修改 *lock,返回 0(失败)


内联汇编实现

NGX_SMP_LOCK

宏定义,在多核(SMP)系统中扩展为 lock 前缀,确保指令的原子性;单核系统中可能为空

cmpxchgl %3, %1

x86 的原子比较并交换指令:

  • 比较 %1(即 *lock)与 eax 寄存器(隐含使用,值为 old
  • 若相等,将 %3(即 set)写入 *lock;否则,将 *lock 的值加载到 eax

sete %0

根据 cmpxchgl 结果(ZF 标志位)设置 res 为 0 或 1

输入输出约束

输出 "=a" (res):结果 res 通过 eax 寄存器返回

输入 "m" (*lock), "a" (old), "r" (set)

*lock 作为内存操作数

old 存入 eax(隐含用于 cmpxchgl 的比较)

set 存入通用寄存器

"cc", "memory":告知编译器条件寄存器和内存可能被修改


内联汇编语法

操作数占位符

  • %0, %1, %2, %3:按操作数出现顺序编号:
    • %0 → "=a" (res)(输出)
    • %1 → "m" (*lock)(输入)
    • %2 → "a" (old)(输入)
    • %3 → "r" (set)(输入)

操作数约束(Constraints)

输出操作数 "=a" (res)

  • =:表示只写(输出)。
  • a:使用 eax 寄存器。
  • res:C变量,接收结果(0或1)

"m" (*lock) 

 m:内存操作数,直接操作 *lock 的内存地址

"a" (old)

 a:将 old 的值存入 eax 寄存器(cmpxchgl 隐式使用 eax 进行比较)。

"r" (set)

 r:将 set 的值存入任意通用寄存器(如 ebxecx 等)。

Clobber列表

  • "cc":表示指令修改了标志寄存器(如 ZF、CF)。
  • "memory":表示指令可能修改内存,强制编译器刷新内存缓存。

cmpxchgl 源操作数, 目标操作数

比较 目标操作数(即 *lock)与 eax 的值(old)。

若相等:

将 源操作数(即 set)写入 目标操作数*lock)。

设置 ZF(Zero Flag)为 1。

若不相等:

将 目标操作数*lock)的值加载到 eax

设置 ZF 为 0。

sete %0

  • sete:若 ZF=1(即比较成功),将目标(%0,即 res)设为 1,否则设为 0。
  • 由于 %0 约束为 "=a",结果通过 eax 写入 res

执行流程

将 old 加载到 eax

原子比较 *lock 与 eax

相等 → 将 set 写入 *lock,ZF=1。

不等 → 将 *lock 值加载到 eax,ZF=0。

根据 ZF 设置 res(1 或 0)。

返回 res


意图

  1. 实现原子操作
    通过 cmpxchgl 指令和 lock 前缀,确保在多核环境下的原子性,避免竞态条件。

  2. 跨平台兼容性

        使用 NGX_SMP_LOCK 宏适配不同平台(如单核无需 lock 前缀)

NGX_SMP_LOCK

在 src\os\unix\ngx_gcc_atomic_x86.h

#if (NGX_SMP)
#define NGX_SMP_LOCK  "lock;"
#else
#define NGX_SMP_LOCK
#endif

objs/ngx_auto_config.h 中

#ifndef NGX_SMP
#define NGX_SMP  1
#endif

所以 NGX_SMP_LOCK 是 "lock;"

  • 无 lockcmpxchgl 本身是原子的,但仅限单核环境。
  • 有 lock:确保多核环境下的原子性,完整执行“比较-交换”操作。

修正 

以上部分 可能是错误的

在 src\os\unix\ngx_atomic.h 中:

#define ngx_trylock(lock)  (*(lock) == 0 && ngx_atomic_cmp_set(lock, 0, 1))

这样定义了 ngx_trylock

但对于 ngx_atomic_cmp_set 的定义可能判断错了

在 我的Ubuntu 环境中 

objs/ngx_auto_config.h:9:#define NGX_HAVE_GCC_ATOMIC  1

也就是在 objs/ngx_auto_config.h 中

定义了 

#ifndef NGX_HAVE_GCC_ATOMIC
#define NGX_HAVE_GCC_ATOMIC  1
#endif

在 ngx_atomic.h 中

#if (NGX_HAVE_LIBATOMIC)
省略
#elif (NGX_HAVE_GCC_ATOMIC)
省略
#define ngx_atomic_cmp_set(lock, old, set)                                    \__sync_bool_compare_and_swap(lock, old, set)

#elif (NGX_HAVE_GCC_ATOMIC) 条件成立

所以 ngx_atomic_cmp_set 的定义应该是:

#define ngx_atomic_cmp_set(lock, old, set)                                    \__sync_bool_compare_and_swap(lock, old, set)

在Ubuntu的x86_64架构下,NGX_HAVE_GCC_ATOMIC会被定义

ngx_atomic_cmp_set 在支持GCC原子内置函数的情况下,这个函数应该会被定义为上述情况

__sync_bool_compare_and_swap 

是 GCC 提供的一个内置原子操作函数,用于实现多线程环境下的无锁同步。其作用是在原子操作中比较并交换(Compare-and-Swap, CAS)一个值,常用于实现线程安全的操作。

函数原型

bool __sync_bool_compare_and_swap(type *ptr, type oldval, type newval);
  • 参数
    • ptr:指向需要操作的内存地址的指针。
    • oldval:期望的旧值。
    • newval:要设置的新值。
  • 返回值
    • 如果 *ptr 的当前值等于 oldval,则将 *ptr 设置为 newval,并返回 true
    • 否则不修改内存,返回 false

底层原理

该函数依赖硬件级别的原子指令(如 x86 的 CMPXCHG 指令)实现,确保多线程环境下操作的原子性

函数由 GCC 编译器直接提供,无需像标准库函数(如 printf)那样通过 #include 引入头文件。

直接在代码中调用即可

gcc -E

鉴于有时预编译指令较多且嵌套,难以判断具体使用的哪一个定义

于是改用 gcc -E 的方法

  • 作用:运行 GCC 的 预处理阶段,处理以下内容:
    • 展开 #include 引入的头文件。
    • 替换 #define 定义的宏。
    • 处理 #ifdef/#if 等条件编译指令。
    • 删除注释。
  • 输出:预处理后的纯 C 代码(未编译)。
gcc -E src/core/ngx_times.c \-I src/core \-I src/event \-I src/event/modules \-I src/os/unix \-I objs \> ngx_times_preprocessed.c

-I 添加头文件搜索路径

> ngx_times_preprocessed.c

  • 作用:将预处理结果重定向到文件 ngx_times_preprocessed.c
  • 文件内容:展开后的完整代码

找到原本 ngx_times.c中

void
ngx_time_update(void)
{u_char          *p0, *p1, *p2, *p3, *p4;ngx_tm_t         tm, gmt;time_t           sec;ngx_uint_t       msec;ngx_time_t      *tp;struct timeval   tv;if (!ngx_trylock(&ngx_time_lock)) {return;}

ngx_time_update 函数中,struct timeval   tv; 后,ngx_trylock 调用的地方

在 ngx_times_preprocessed.c 中的位置

 if (!(*(&ngx_time_lock) == 0 && __sync_bool_compare_and_swap(&ngx_time_lock, 0, 1))) {return;}

这里是展开后的样子

所以 确认是 调用了

__sync_bool_compare_and_swap

 

相关文章:

Ubuntu 下 nginx-1.24.0 源码分析 - ngx_atomic_cmp_set 函数

目录 修正 执行 ./configure 命令时,输出: checking for OS Linux 6.8.0-52-generic x86_64 checking for C compiler ... found using GNU C compiler gcc version: 11.4.0 (Ubuntu 11.4.0-1ubuntu1~22.04) 所以当前环境是 x86_64 于是在 src…...

CNN-BiLSTM卷积神经网络双向长短期记忆神经网络多变量多步预测,光伏功率预测

代码地址:CNN-BiLSTM卷积神经网络双向长短期记忆神经网络多变量多步预测,光伏功率预测 CNN-BiLSTM卷积神经网络双向长短期记忆神经网络多变量多步预测 一、引言 1.1、研究背景和意义 光伏功率预测在现代电力系统中占有至关重要的地位。随着可再生能源…...

【YOLO系列】YOLOv5 NMS源码理解、更换为DIoU-NMS

代码来源:GitHub - ultralytics/yolov5: YOLOv5 🚀 in PyTorch > ONNX > CoreML > TFLite 使用的代码是YOLOv5 6.1版本 参考笔记:YOLOv5改进系列(八) 更换NMS非极大抑制DIoU-NMS、CIoU-NMS、EIoU-NMS、GIoU-NMS 、SIoU-NMS、Soft-…...

Android RenderEffect对Bitmap高斯模糊(毛玻璃),Kotlin(1)

Android RenderEffect对Bitmap高斯模糊(毛玻璃),Kotlin(1) import android.graphics.Bitmap import android.graphics.BitmapFactory import android.graphics.HardwareRenderer import android.graphics.PixelFormat import android.graphic…...

【linux学习指南】线程同步与互斥

文章目录 📝线程互斥🌠 库函数strncpy🌉进程线程间的互斥相关背景概念🌉互斥量mutex 🌠线程同步🌉条件变量🌉同步概念与竞态条件🌉 条件变量函数 🚩总结 📝线…...

JavaScript函数与方法详解

目录 一、函数的定义 1. 函数声明 2. 函数表达式 3. 箭头函数 二、函数的调用 1. 调用方式 2. 参数数量的灵活性 三、arguments 对象 1. 基本概念 2. 属性 3. 应用场景 4. 转换为真数组 5. 总结 四、Rest参数 1. 基本概念 2. 特点 3. 应用场景 4. 总结 五、变…...

【论文笔记】ZeroGS:扩展Spann3R+GS+pose估计

spann3r是利用dust3r做了增量式的点云重建,这里zeroGS在前者的基础上,进行了增量式的GS重建以及进行了pose的联合优化,这是一篇dust3r与GS结合的具有启发意义的工作。 abstract NeRF和3DGS是重建和渲染逼真图像的流行技术。然而,…...

AtCoder - arc058_d Iroha Loves Strings解答与注意事项

链接:Iroha Loves Strings - AtCoder arc058_d - Virtual Judge 利用bitset这一数据结构,定义bitset类型的变量dp[i]表示第i到n个字符串能拼成的字符串长度都有哪些,比如00100101,表示能拼成的长度有0,2,5,&#xff0…...

企业使用统一终端管理(UEM)工具提高端点安全性

什么是统一终端管理(UEM) 统一终端管理(UEM)是一种从单个控制台管理和保护企业中所有端点的方法,包括智能手机、平板电脑、笔记本电脑、台式机和 IoT设备。UEM 解决方案为 IT 管理员提供了一个集中式平台,用于跨所有作系统和设备类型部署、配置、管理和…...

Leetcode 算法题 9 回文数

起因, 目的: 数学法。 % 求余数, 拆开组合,组合拆开。 这个题,翻来覆去,拆开组合, 组合拆开。构建的过程。 题目来源,9 回文数: https://leetcode.cn/problems/palindrome-number…...

设计模式Python版 命令模式(上)

文章目录 前言一、命令模式二、命令模式示例 前言 GOF设计模式分三大类: 创建型模式:关注对象的创建过程,包括单例模式、简单工厂模式、工厂方法模式、抽象工厂模式、原型模式和建造者模式。结构型模式:关注类和对象之间的组合&…...

C语言之循环结构:直到型循环

C语言 循环结构 直到型循环的实现 特点:先执行,后判断,不管条件是否满足,至少执行一次。典型代表:do…while,goto(已淘汰,不推荐使用) do…while 语法: d…...

细说STM32F407单片机RTC的备份寄存器原理及使用方法

目录 一、备份寄存器的功能 二、示例功能 三、项目设置 1、晶振、DEBUG、CodeGenerator、USART6 2、RTC 3、NVIC 4、GPIO 及KEYLED 四、软件设计 1、main.h 2、main.c 3、rtc.c 4、keyled.c、keyled.h 五、运行调试 本实例旨在介绍备份寄存器的作用。本实例继续使…...

MATLAB计算反映热需求和能源消耗的度数日指标(HDD+CDD)(全代码)

目录 度数日(Degree Days, DD)概述计算公式MATLAB计算代码调用函数1:计算单站点的 CDD参考度数日(Degree Days, DD)概述 度数日(Degree Days, DD)是用于衡量建筑、城市和地区的热需求和能源消耗模式的指标。它分为两部分: 加热度日(Heating Degree Days, HDD):当室…...

J6 X8B/X3C切换HDR各帧图像

1、OV手册上的切换命令 寄存器为Ox5074 各帧切换: 2、地平线control tool实现切换命令 默认HDR模式出图: HCG出图: LCG出图 SPD出图 VS出图...

09-轮转数组

给定一个整数数组 nums,将数组中的元素向右轮转 k 个位置,其中 k 是非负数。 方法一:使用额外数组 function rotate(nums: number[], k: number): void {const n nums.length;k k % n; // 处理 k 大于数组长度的情况const newNums new A…...

用vue3写一个好看的wiki前端页面

以下是一个使用 Vue 3 Element Plus 实现的 Wiki 风格前端页面示例&#xff0c;包含现代设计、响应式布局和常用功能&#xff1a; <template><div class"wiki-container"><!-- 头部导航 --><el-header class"wiki-header"><d…...

瑞芯微烧写工具

文章目录 前言一、安装驱动二、安装烧写工具1.直接解压压缩包2. 如何使用 三、MASKROM 裸机必备四、LOADER 烧写&#xff0c;前提是搞过第三步没问题五、Update.img包的烧录六、linux下烧写总结 前言 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1a; 项目需要…...

说下JVM中一次完整的GC流程?

大家好&#xff0c;我是锋哥。今天分享关于【说下JVM中一次完整的GC流程?】面试题。希望对大家有帮助&#xff1b; 说下JVM中一次完整的GC流程? 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 JVM中的一次完整的垃圾回收&#xff08;GC&#xff09;流程可以概括为…...

Open FPV VTX开源之OSD使用分类

Open FPV VTX开源之OSD使用分类 1. 源由2. 硬件2.1 【天空端】SigmaStar2.2 【天空端】Raspberry Pi2.3 【地面端】 3. 软件3.1 天空端软件3.2 地面端软件 4. 分类4.1 嵌入式OSD分类A1-嵌入式OSD&#xff1a;SigmaStar Android分类A2-嵌入式OSD&#xff1a;SigmaStar Hi3536分…...

逻辑回归:给不确定性划界的分类大师

想象你是一名医生。面对患者的检查报告&#xff08;肿瘤大小、血液指标&#xff09;&#xff0c;你需要做出一个**决定性判断**&#xff1a;恶性还是良性&#xff1f;这种“非黑即白”的抉择&#xff0c;正是**逻辑回归&#xff08;Logistic Regression&#xff09;** 的战场&a…...

蓝牙 BLE 扫描面试题大全(2):进阶面试题与实战演练

前文覆盖了 BLE 扫描的基础概念与经典问题蓝牙 BLE 扫描面试题大全(1)&#xff1a;从基础到实战的深度解析-CSDN博客&#xff0c;但实际面试中&#xff0c;企业更关注候选人对复杂场景的应对能力&#xff08;如多设备并发扫描、低功耗与高发现率的平衡&#xff09;和前沿技术的…...

C++ 基础特性深度解析

目录 引言 一、命名空间&#xff08;namespace&#xff09; C 中的命名空间​ 与 C 语言的对比​ 二、缺省参数​ C 中的缺省参数​ 与 C 语言的对比​ 三、引用&#xff08;reference&#xff09;​ C 中的引用​ 与 C 语言的对比​ 四、inline&#xff08;内联函数…...

【android bluetooth 框架分析 04】【bt-framework 层详解 1】【BluetoothProperties介绍】

1. BluetoothProperties介绍 libsysprop/srcs/android/sysprop/BluetoothProperties.sysprop BluetoothProperties.sysprop 是 Android AOSP 中的一种 系统属性定义文件&#xff08;System Property Definition File&#xff09;&#xff0c;用于声明和管理 Bluetooth 模块相…...

C++ Visual Studio 2017厂商给的源码没有.sln文件 易兆微芯片下载工具加开机动画下载。

1.先用Visual Studio 2017打开Yichip YC31xx loader.vcxproj&#xff0c;再用Visual Studio 2022打开。再保侟就有.sln文件了。 易兆微芯片下载工具加开机动画下载 ExtraDownloadFile1Info.\logo.bin|0|0|10D2000|0 MFC应用兼容CMD 在BOOL CYichipYC31xxloaderDlg::OnIni…...

Reasoning over Uncertain Text by Generative Large Language Models

https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829 1. 概述 文本中的不确定性在许多语境中传达,从日常对话到特定领域的文档(例如医学文档)(Heritage 2013;Landmark、Gulbrandsen 和 Svenevei…...

在Ubuntu24上采用Wine打开SourceInsight

1. 安装wine sudo apt install wine 2. 安装32位库支持,SourceInsight是32位程序 sudo dpkg --add-architecture i386 sudo apt update sudo apt install wine32:i386 3. 验证安装 wine --version 4. 安装必要的字体和库(解决显示问题) sudo apt install fonts-wqy…...

【无标题】路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论

路径问题的革命性重构&#xff1a;基于二维拓扑收缩色动力学模型的零点隧穿理论 一、传统路径模型的根本缺陷 在经典正方形路径问题中&#xff08;图1&#xff09;&#xff1a; mermaid graph LR A((A)) --- B((B)) B --- C((C)) C --- D((D)) D --- A A -.- C[无直接路径] B -…...

深度学习水论文:mamba+图像增强

&#x1f9c0;当前视觉领域对高效长序列建模需求激增&#xff0c;对Mamba图像增强这方向的研究自然也逐渐火热。原因在于其高效长程建模&#xff0c;以及动态计算优势&#xff0c;在图像质量提升和细节恢复方面有难以替代的作用。 &#x1f9c0;因此短时间内&#xff0c;就有不…...

AirSim/Cosys-AirSim 游戏开发(四)外部固定位置监控相机

这个博客介绍了如何通过 settings.json 文件添加一个无人机外的 固定位置监控相机&#xff0c;因为在使用过程中发现 Airsim 对外部监控相机的描述模糊&#xff0c;而 Cosys-Airsim 在官方文档中没有提供外部监控相机设置&#xff0c;最后在源码示例中找到了&#xff0c;所以感…...