【问题标题】:problem with O_DIRECT IO with aligned stack buffer对齐堆栈缓冲区的 O_DIRECT IO 问题
【发布时间】:2011-09-08 11:00:21
【问题描述】:

当缓冲区在堆栈上时,以下代码会失败,但在堆上分配时会成功。我在带有 Raid 驱动器的 RHEL 5.3 上对其进行了测试。是否可以将 O_DIRECT 与堆栈缓冲区一起使用?

#define _GNU_SOURCE
#include <stdio.h>
#include <assert.h>
#include <malloc.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>
#include <sys/mman.h>
#include <malloc.h>


#define K 1024
#define ALIGNMENT (4*K)
#define RDSIZE (16*K)
#define BLOCKSIZE (512*K)

int main()
{
    int flags = O_RDONLY |  O_LARGEFILE;
    int n = 0;
    int fd = 0;
    char* buf = (char *) memalign(ALIGNMENT, BLOCKSIZE);
    //char buf[BLOCKSIZE] __attribute__((__aligned__(ALIGNMENT)));

    assert(((long)buf) % ALIGNMENT == 0);

    fd = open("test", flags | O_DIRECT);
    if (fd < 0) {
        perror("file open");
        return -1;
    }


    n = read(fd, buf, RDSIZE);

    if (n < 0) {
        perror("file read");
        return -1;
    }

    printf("%d\n", n);

    close(fd);

}

更新:使用 Intel CC 编译时相同的代码成功。

【问题讨论】:

  • +1 提出了一个很好的问题。我假设 assert() 成功而 open() 失败?什么是 perror() 打印?
  • 旁注:#define ALIGNMENT (4*K) 等等。否则你会遇到麻烦,因为 C 预处理器是基于令牌的。见C FAQ 10.1
  • 很好地抓住了宏观问题,这是对问题的快速而肮脏的再现,所以请原谅我的不良风格
  • 打开成功。使用带有错误打印无效参数的堆栈缓冲区时读取失败。
  • 好的,这看起来确实像一个编译器错误。您的程序在 Ubuntu Natty (gcc 4.5.2)、CentOS 5.5 (gcc 4.1.2) 和 Suse 11 SP1 (gcc 4.3.4) 上运行良好。如果要调试编译器,请使用“-S”编译生成 foo.s,然后将其发布到某处...

标签: c io alignment


【解决方案1】:

检查您的堆栈大小 512K 相当多。

【讨论】:

  • 这是一台 64 位机器。这应该不是问题
【解决方案2】:

如果问题是 gcc 未对齐 buf,请尝试使用此便携式版本:

char x_buf[BLOCKSIZE+PAGE_SIZE];
char *buf = buf + (PAGE_SIZE-1 & -(uintptr_t)x_buf);

【讨论】:

  • 这不是问题,断言通过时缓冲区已正确对齐。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-02-23
  • 1970-01-01
  • 2012-11-23
  • 1970-01-01
  • 1970-01-01
  • 2022-10-17
  • 1970-01-01
相关资源
最近更新 更多