OSX缺乏memalign

我正在研究C中的一个项目,它需要memalign()。 真的,posix_memalign()也会这样做,但是darwin / OSX缺乏这两者。

什么是鞋拔的好方法? 我不理解posix-C代码的许可,如果我要删掉memalign.c并把它放在我的项目中 – 我不希望任何病毒式许可LGPL-ing我的整个项目。

Mac OS X似乎是16字节的mem对齐。

从网站引用:

我很难在MacOS X内存对齐上找到明确的声明,所以我做了自己的测试。 在10.4 / intel上,堆栈和堆内存都是16字节对齐的。 因此移植软件的人可以停止寻找memalign()和posix_memalign()。 这不是必需的。

应该很容易做到自己,不是吗? 像下面的东西(未测试):

 void *aligned_malloc( size_t size, int align ) { void *mem = malloc( size + (align-1) + sizeof(void*) ); char *amem = ((char*)mem) + sizeof(void*); amem += align - ((uintptr)amem & (align - 1)); ((void**)amem)[-1] = mem; return amem; } void aligned_free( void *mem ) { free( ((void**)mem)[-1] ); } 

(感谢Jonathan Leffler )

编辑:关于剥离另一个memalign实现,问题不是许可。 相反,你遇到的困难是任何好的memalign实现都将成为堆管理器代码库不可或缺的一部分,而不是简单地分层在malloc / free之上。 因此,将它移植到不同的堆管理器时会遇到严重问题,尤其是当您无法访问它的内部时。

更新:OSX现在有posix_memalign()

晚到派对,但OSX的新版本确实posix_memalign() 。 在对齐页面边界时,您可能需要这样做。 例如:

 #include  char *buffer; int pagesize; pagesize = sysconf(_SC_PAGE_SIZE); if (pagesize == -1) handle_error("sysconf"); if (posix_memalign((void **)&buffer, pagesize, 4 * pagesize) != 0) { handle_error("posix_memalign"); } 

需要注意的一点是,与memalign()不同, posix_memalign()**buffer作为参数并返回整数错误代码。

为什么要移植的软件需要memalign()或posix_memalign()? 它是否用于比austirg引用的16字节对齐更大的对齐?

我看到Mike F发布了一些代码 – 它看起来相对简洁,但我认为while循环可能是次优的(如果所需的对齐是1KB,它可能会迭代很多次)。

不:

 amem += align - ((uintptr)amem & (align - 1)); 

在一次手术中到达那里?

从macosx手册页:

malloc(),calloc(),valloc(),realloc()和reallocf()函数分配内存。 对齐分配的内存,使其可用于任何数据类型,包括AltiVec和SSE相关类型。 free()函数释放通过前面的分配函数创建的分配。

是的Mac OS X在ABI中 确实有16个字节内存对齐 。 你不应该使用memalign()。 如果你的内存需求是16的因素,那么我就不会实现它,也许只是添加一个断言。

如果你需要一个任意对齐的malloc,请查看x264的malloc(git存储库中的common / common.c),它有一个没有malloc.h的系统的自定义memalign。 它非常简单的代码,我甚至不认为它具有版权,但你应该很容易在看到之后实现自己的代码。

当然,如果你只需要16字节对齐,如上所述,它在OS X ABI中。

可能值得建议在代码中使用Doug Lea的malloc。 链接文字

感谢您的帮助,伙计……帮助我的情况(OpenCascade src / Image / Image_PixMap.cxx,OSX10.5.8 PPC)

结合上面的答案,如果不是特别熟悉malloc等,这可能会节省一些人在挖掘或灌输希望:

我正在构建的相当大的项目只有一个对posix_memalign的引用,结果发现它是一堆预处理器条件的结果,不包括OSX但是DID包括BORLANDC,这证实了其他人对其安全性的建议。在某些情况下使用malloc:

 #if defined(_MSC_VER) return (TypePtr )_aligned_malloc (theBytesCount, theAlign); #elif (defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 1) return (TypePtr ) _mm_malloc (theBytesCount, theAlign); #elif defined(__BORLANDC__) return (TypePtr ) malloc (theBytesCount); #else void* aPtr; if (posix_memalign (&aPtr, theAlign, theBytesCount)) { aPtr = NULL; } return (TypePtr )aPtr; #endif 

因此,它可以像使用malloc一样简单,正如其他人所建议的那样。

例如:在__GNUC__之上移动__BORLANDC__条件并添加APPLE

 #elif (defined(__BORLANDC__) || defined(__APPLE__)) //now above `__GNUC__` 

注意:我没有检查BORLANDC是否像上面提到的操作系统X那样使用16字节对齐。 我也没有validationPPC OS X的确如此。 但是,这种用法表明这种对齐并不是特别重要。 (这里希望它有效,而且搜索者也可以这么容易!)