如何在Linux,x86,arm,GCC和icc上执行primefaces操作?
每一个现代操作系统都提供了一些primefaces操作
-  Windows有Interlocked*API
-   FreeBSD有<machine/atomic.h>
-   Solaris有<atomic.h>
-   Mac OS X有<libkern/OSAtomic.h>
任何这样的Linux?
- 我需要它在大多数Linux支持的平台上工作,包括:x86,x86_64和arm 。
- 我需要它在至lessGCC和英特尔编译器上工作。
- 我不需要像glib或qt那样使用第三个库文件。
- 我需要它在C ++中工作(C不需要)
问题:
-  所有平台(ARM)均不支持GCCprimefaces内置__sync_*,英特尔编译器不支持。
-   AFAIK <asm/atomic.h>不应该在用户空间中使用,我没有成功地使用它。 另外,我不确定它是否会与英特尔编译器一起工作。
有什么build议么?
 我知道有很多相关的问题,但其中一些指向__sync* ,这对我来说是不可行的(ARM),有些则指向asm/atomic.h 。 
也许有一个内联汇编库为GCC做这个(ICC支持gcc汇编)?
编辑:
有一个非常局部的解决scheme,只允许添加操作(允许实现primefaces计数器但不locking需要CAS的自由结构):
 如果使用libstc++ (Intel编译器使用libstdc++ ),则可以使用在<ext/atomicity.h>或<bits/atomicity.h>中定义的__gnu_cxx::__exchange_and_add 。 取决于编译器版本。 
不过,我仍然希望看到支持CAS的东西。
项目正在使用这个:
http://packages.debian.org/source/sid/libatomic-ops
如果你想要简单的操作,如CAS,你不能只使用特定于内核的特定实现,并用autotools / cmake在用户空间中进行检查吗? 就许可证而言,尽pipe内核是GPL,但我认为这是由Intel / AMD提供的内联程序集,而不是内核拥有许可证。 它们恰好在内核源代码中以易于访问的forms出现。
C&C ++最近的标准(从2011年开始)现在指定了primefaces操作:
-   C11: stdatomic.h
-   C ++ 11: std::atomic
无论如何,您的平台或编译器可能不支持这些较新的标题和function。
该死。 我会build议海湾合作委员会的原语,然后你说他们是没有限制的。 🙂
 在这种情况下,我会为每个您关心的架构/编译器组合编写一个#ifdef ,并对内联asm进行编码。 也许检查__GNUC__或者一些类似的macros,如果它们可用,就使用GCC原语,因为它感觉使用这些更为正确。  🙂 
你会有很多的重复,并且可能很难validation正确性,但是这似乎是很多项目做这个的方式,而且我已经有了很好的结果。
 过去有些陷阱:在使用GCC的时候,不要忘记“ asm volatile ”和"memory" , "cc"等等。 
具有非侵入性许可的Boost和其他框架已经提供了便携式primefaces计数器 – 只要它们在目标平台上得到支持即可。
第三方库对我们有好处。 如果由于奇怪的原因你的公司禁止你使用它们,你仍然可以看看它们如何继续(只要许可证允许它使用)来实现你正在寻找的东西。
我最近做了一个这样的事情,我遇到了和你一样的困难。 我的解决scheme基本如下:
- 尝试使用特征macros来检测gcc内置函数
-  如果不可用的话,只需用cmpxch和__asm__来实现其他体系结构(ARM比这更复杂一点)。 只要做一个可能的大小,例如sizeof(int)。
-  使用inline函数在一个或两个基元上实现所有其他function
GCC有一个补丁来支持ARMprimefaces操作。 在英特尔上不会帮助你,但是你可以检查代码 – 最近有一些内核支持旧的ARM体系结构,而新的内核支持内置的指令,所以你应该能够构build一些可行的方法。
  __sync*当然是(已经)被英特尔编译器支持,因为GCC从那里采用了这些插件。 阅读本页面的第一段。 另请参阅“ 用于Linux * Intrinsics参考的英特尔®C ++编译器参考 ”(第198页)。它是从2006年开始的 ,详细描述了这些内置的function。 
对于ARM的支持,对于以前的ARM CPU来说:它不能完全在用户空间中完成,但可以在内核空间中完成(通过在操作期间禁止中断),我想我已经在某个地方读了一段时间的支持。
 根据__sync_*年10月8日这个PHP错误 , __sync_*将只能失败 
- PA-RISC与Linux以外的其他产品兼容
- SPARCv7和更低
- ARM与GCC <4.3
- ARMv5以及Linux以外的版本
- MIPS1
所以在GCC> 4.3(现在是4.7)的情况下,ARMv6和更新版本不应该有问题。 只要为Linux编译,就不应该对ARMv5有任何问题。
在Debian / Ubuntu推荐…
sudo apt-get install libatomic-ops-dev
示例: http : //www.hpl.hp.com/research/linux/atomic_ops/example.php4
GCC和ICC兼容。
与使用primefaces<T>的英特尔线程构build模块(TBB)相比,libatomic-ops-dev速度提高了一倍! (英特尔编译器)
在Ubuntu i7生产者 – 消费者线程上testing在0.5secs下环形缓冲区连接1000万英寸而不是TBE的1.2secs
和易于使用,例如
不稳定的AO_t头;
AO_fetch_and_add1(头);
 请参阅: kernel_user_helpers.txt或entry-arm.c并查找__kuser_cmpxchg 。 从其他ARM Linux版本的评论中可以看出, 
kuser_cmpxchg
位置:0xffff0fc0 参考原型: int __kuser_cmpxchg(int32_t oldval,int32_t newval,volatile int32_t * ptr); input: r0 = oldval r1 = newval r2 = ptr lr =返回地址 输出: r0 =成功代码(零或非零) C标志=如果r0 == 0则设置,如果r0!= 0则清除 Clobbered寄存器: r3,ip,标志 定义: 只有在* ptr等于oldval的情况下,才会在* ptr中存储newval。 如果* ptr更改则返回零,如果不发生交换则返回非零。 如果* ptr被改变以允许组装,C标志也被设置 调用代码中的优化。 用法示例:
  typedef int (__kuser_cmpxchg_t)(int oldval, int newval, volatile int *ptr); #define __kuser_cmpxchg (*(__kuser_cmpxchg_t *)0xffff0fc0) int atomic_add(volatile int *ptr, int val) { int old, new; do { old = *ptr; new = old + val; } while(__kuser_cmpxchg(old, new, ptr)); return new; } 
笔记:
- 这个例程已经包含了需要的内存障碍。
- 仅当__kuser_helper_version> = 2(来自内核版本2.6.12)时才有效。
 这是使用Linux与ARMv3使用swp原语。 你必须有一个非常古老的ARM来支持这个。 只有数据中止或中断可能导致旋转失败,所以内核监视这个地址〜0xffff0fc0,并在数据中止或中断发生时执行用户空间 PC修复。 所有支持ARMv5及更低版本的用户空间库都将使用此工具。 
例如, QtConcurrent使用这个。