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_MEMALIGN和NGX_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 #endifNGX_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中。- 如果分配失败,返回非零的错误码(如
EINVAL或ENOMEM)
posix_memalign
错误处理
if (err) { ngx_log_error(NGX_LOG_EMERG, log, err, "posix_memalign(%uz, %uz) failed", alignment, size); p = NULL; }
- 作用 :
- 如果
posix_memalign返回非零值(即分配失败),执行以下操作:
- 调用
ngx_log_error记录错误日志。
- 日志级别为
NGX_LOG_EMERG,表示这是一个严重的错误。- 日志内容包括错误码
err和具体的分配参数(alignment和size)。- 将
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是有效的内存地址;如果分配失败,p为NULL。