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

发布于:2025-02-18 ⋅ 阅读:(121) ⋅ 点赞:(0)

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

网站公告

今日签到

点亮在社区的每一天
去签到