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

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

ngx_memalign

声明在 src/os/unix/ngx_alloc.h

/*
 * Linux has memalign() or posix_memalign()
 * Solaris has memalign()
 * FreeBSD 7.0 has posix_memalign(), besides, early version's malloc()
 * aligns allocations bigger than page size at the page boundary
 */

#if (NGX_HAVE_POSIX_MEMALIGN || NGX_HAVE_MEMALIGN)

void *ngx_memalign(size_t alignment, size_t size, ngx_log_t *log);

#else

#define ngx_memalign(alignment, size, log)  ngx_alloc(size, log)

#endif

注释部分

/*
 * Linux has memalign() or posix_memalign()
 * Solaris has memalign()
 * FreeBSD 7.0 has posix_memalign(), besides, early version's malloc()
 * aligns allocations bigger than page size at the page boundary
 */
作用:
  • 这段注释描述了不同操作系统提供的内存对齐分配函数。
  • Linux 提供了两种内存对齐函数:memalign()posix_memalign()
  • Solaris 提供了 memalign()
  • FreeBSD 7.0 提供了 posix_memalign(),并且在早期版本中,malloc() 对大于页面大小的内存分配会自动对齐到页面边界。

条件编译宏

#if (NGX_HAVE_POSIX_MEMALIGN || NGX_HAVE_MEMALIGN) 
作用:
  • 这是一个条件编译指令,用于判断当前系统是否支持 posix_memalign()memalign()
  • NGX_HAVE_POSIX_MEMALIGNNGX_HAVE_MEMALIGN 是预定义的宏,通常由 Nginx 的配置脚本(如 configure 脚本)根据目标系统的特性设置。
    • 如果系统支持 posix_memalign(),则 NGX_HAVE_POSIX_MEMALIGN 被定义为 1。
    • 如果系统支持 memalign(),则 NGX_HAVE_MEMALIGN 被定义为 1。

在 objs/ngx_auto_config.h

#ifndef NGX_HAVE_POSIX_MEMALIGN
#define NGX_HAVE_POSIX_MEMALIGN  1
#endif


#ifndef NGX_HAVE_MEMALIGN
#define NGX_HAVE_MEMALIGN  1
#endif

NGX_HAVE_POSIX_MEMALIGN

NGX_HAVE_MEMALIGN

都被定义为 1

所以 #if (NGX_HAVE_POSIX_MEMALIGN || NGX_HAVE_MEMALIGN)   成立

定义 ngx_memalign 函数 

void *ngx_memalign(size_t alignment, size_t size, ngx_log_t *log);
  • alignment:指定内存对齐的字节边界(例如 16 字节、64 字节等)。
  • size:需要分配的内存大小。
  • log:日志对象,用于记录错误或调试信息。

实现

在 src\os\unix\ngx_alloc.c

#if (NGX_HAVE_POSIX_MEMALIGN)

void *
ngx_memalign(size_t alignment, size_t size, ngx_log_t *log)
{
    void  *p;
    int    err;

    err = posix_memalign(&p, alignment, size);

    if (err) {
        ngx_log_error(NGX_LOG_EMERG, log, err,
                      "posix_memalign(%uz, %uz) failed", alignment, size);
        p = NULL;
    }

    ngx_log_debug3(NGX_LOG_DEBUG_ALLOC, log, 0,
                   "posix_memalign: %p:%uz @%uz", p, size, alignment);

    return p;
}

#if (NGX_HAVE_POSIX_MEMALIGN)    条件成立


使用

gcc -E src/os/unix/ngx_alloc.c \
	-I src/core \
	-I src/event \
	-I src/event/modules \
	-I src/os/unix \
	-I objs \
	> ngx_alloc_preprocessed.c

查看处理后的输出文件,查找 ngx_memalign

void *
ngx_memalign(size_t alignment, size_t size, ngx_log_t *log)
{
    void *p;
    int err;

    err = posix_memalign(&p, alignment, size);

    if (err) {
        if ((log)->log_level >= 1) ngx_log_error_core(1, log, err, "posix_memalign(%uz, %uz) failed", alignment, size)
                                                                         ;
        p = 
# 62 "src/os/unix/ngx_alloc.c" 3 4
           ((void *)0)
# 62 "src/os/unix/ngx_alloc.c"
               ;
    }

   
                                                                     ;

    return p;
}

可以确定当下环境中所使用的具体实现是 调用 posix_memalign 函数的这一个

详解 

函数定义

void *
ngx_memalign(size_t alignment, size_t size, ngx_log_t *log)
  • 作用 :定义了一个函数 ngx_memalign,用于分配一块对齐的内存。
  • 参数
    • alignment:指定内存对齐的边界(以字节为单位)。例如,8 表示分配的内存地址必须是 8 的倍数。
    • size:需要分配的内存大小(以字节为单位)。
    • log:指向一个日志对象,用于记录错误或调试信息。
  • 返回值 :返回分配的内存指针(void * 类型),如果分配失败则返回 NULL

变量声明 

void  *p;
int    err;
  • 作用
    • p:用于存储分配的内存地址。
    • err:用于存储 posix_memalign 函数的返回值,表示分配操作的结果。

调用 posix_memalign 分配内存

err = posix_memalign(&p, alignment, size);

 

  • 作用
    • 调用 POSIX 标准库函数 posix_memalign,尝试分配一块满足对齐要求的内存。
    • 参数说明:
      • &p:指向存储分配结果的指针地址。
      • alignment:对齐边界。
      • size:需要分配的内存大小。
    • 返回值:
      • 如果分配成功,posix_memalign 返回 0,并将分配的内存地址存储到 p 中。
      • 如果分配失败,返回非零的错误码(如 EINVALENOMEM

posix_memalign

posix_memalign 函数-CSDN博客

错误处理

if (err) {
    ngx_log_error(NGX_LOG_EMERG, log, err,
                  "posix_memalign(%uz, %uz) failed", alignment, size);
    p = NULL;
}

 

  • 作用
    • 如果 posix_memalign 返回非零值(即分配失败),执行以下操作:
      1. 调用 ngx_log_error 记录错误日志。
        • 日志级别为 NGX_LOG_EMERG,表示这是一个严重的错误。
        • 日志内容包括错误码 err 和具体的分配参数(alignmentsize)。
      2. p 设置为 NULL,确保函数在分配失败时返回一个无效指针。

调试日志

ngx_log_debug3(NGX_LOG_DEBUG_ALLOC, log, 0,
               "posix_memalign: %p:%uz @%uz", p, size, alignment);

 

  • 作用
    • 调用 ngx_log_debug3 记录调试信息。
    • 日志内容包括:
      • 分配的内存地址 p
      • 分配的内存大小 size
      • 对齐边界 alignment

返回分配结果

return p;

 

  • 作用
    • 返回分配的内存指针 p
    • 如果分配成功,p 是有效的内存地址;如果分配失败,pNULL

相关文章:

  • van-field的maxlength属性为空会导致输入框的值被清空。
  • SSML语音合成标记语言开发指南:从基础语法到实战案例解析
  • [250217] x-cmd 发布 v0.5.3:新增 DeepSeek AI 模型支持及飞书/钉钉群机器人 Webhook 管理
  • windows 设置poppler
  • unordered_set 和 unordered_map的模拟实现(c++)
  • 【Go入门篇】第一章:从 Java/Python 开发者的视角入门go语言
  • 半导体制造中的“魔法盾牌”:二氧化硅
  • 前端知识速记--HTML篇:HTML5的新特性
  • vLLM专题(六)-Pooling模型
  • floodfill算法系列一>扫雷游戏
  • vue基础(十)
  • 如何使用 Ollama 在本地设置和运行 DeepSeek R1
  • 如何使用 Docker 搭建 FastAPI 环境, 本地仅编辑代码
  • 力扣LeetCode: 931 下降路径最小和
  • 【小白学AI系列】NLP 核心知识点(七)Embedding概念介绍
  • 【Elasticsearch】`nested`字段
  • 巨控GRM530系列的远程模块用于PLC远程上下载方案
  • 9.综合调试|输入不能存在空格|desc存在None|输出权值和ID|函数重名|修改文件名|权值和实际关键词出现次数(C++)
  • 网工项目理论1.10 路由结构设计
  • 999感冒灵抖音KOL内容营销案例拆解
  • 马上评丨又见酒店坐地起价,“老毛病”不能惯着
  • 外交部:印度香客赴中国西藏神山圣湖朝圣将于今年夏季恢复
  • 柴德赓、纪庸与叫歇碑
  • QFII一季度现身超300家公司:持有南京银行市值最高,5家青睐立航科技
  • 六部门:进一步优化离境退税政策扩大入境消费
  • 坤莹·帕塔玛·利斯达特拉任世界羽联主席