是否有任何小型库,将各种处理器的类似 CAS 的操作包装成宏或函数,可以跨多个编译器移植?
PS。atomic.hpp库位于 boost::interprocess::detail 命名空间内。作者拒绝让它成为一个公共的、维护良好的图书馆。
让我们重新打开这个问题,看看是否还有其他选择?
是否有任何小型库,将各种处理器的类似 CAS 的操作包装成宏或函数,可以跨多个编译器移植?
PS。atomic.hpp库位于 boost::interprocess::detail 命名空间内。作者拒绝让它成为一个公共的、维护良好的图书馆。
让我们重新打开这个问题,看看是否还有其他选择?
OPA(开放便携式原子)可能非常适合您的需求。 https://trac.mcs.anl.gov/projects/openpa/
它在 MIT 风格的许可下为跨多个平台的常见原子操作提供一致的 C API。图书馆很小,当然可以满足您的大小要求。当前平台列表为:
我从来没有在 C++ 程序中使用过它,尽管它应该可以在很少或没有变化的情况下工作。如果您遇到麻烦,我很乐意对其进行调整(只需发送邮件 opa-discuss@lists.mcs.anl.gov)。
boost 进程间库可能是您所追求的——Atomic.hpp 包含文件包含适用于各种平台和编译器的比较和交换实现。
Intel Threading Building Blocks有一个很好的可移植atomic<T>
模板,可以满足您的需求。但是否是小型图书馆当然可以争论。
你可能对Glib 的原子操作函数感兴趣,
g_atomic_int_compare_and_exchange()
为各种架构实现 CAS 语义。实现本身比较容易理解,可以独立使用,不需要太多努力,你可以在 svn.gnome.org/viewvc/ 下的 glib/trunk/glib/gatomic.{c,h} 下找到它。希望这可以帮助!
在 Mac OS X 和 Windows 上,无论如何都应该使用内置的 CompareAndSwap 函数(分别为 InterlockedCompareExchange() 和 OSAtomicCompareAndSwapPtrBarrier())。因此,无论这些平台上的编译器如何,都可以工作。
在其他 Unix 上,这有点棘手,如果您使用的是 GCC 4.1 或更高版本,您可以只使用其内置的 __sync_val_compare_and_swap(),尽管并非所有的 unix 编译器都支持合理的 gcc 扩展,因为许多源自 Linux 的代码假定它们存在.
因此,如果您想以一种适用于 OS X 和 Windows 上所有处理器的大多数编译器以及其他平台上的 GCC 和其他一些编译器的方式将它们包装起来,您应该执行以下操作:
boolean CompareAndSwapPointer(volatile * void * ptr,
void * new_value,
void * old_value) {
#if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1050
return OSAtomicCompareAndSwapPtr (old_value, new_value, ptr);
#elif defined(_MSC_VER)
return InterlockedCompareExchange(ptr, new_value, old_value);
#elif (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) > 40100
return __sync_val_compare_and_swap(ptr, old_value, new_value);
#else
# error No implementation
#endif
}
那没有经过测试,但我认为它应该是正确的。请注意所有操作系统库如何以不同的顺序获取参数 ;-)
显然,您可以为不同大小的比较和交换做几个版本,如果需要,可以将它们包装在模板中。API 大多是基于 C 的,并将类型信息编码到函数中,这对于习惯于通过模板参数化类型的人来说有点讨厌。
Boehm 有atomic_ops项目的库。不过,不知道许可证。
有一个提议的 C++0x 兼容的 Boost atomics 库: http: //www.chaoticmind.net/~hcb/projects/boost.atomic/
这个库的目的是为 boost 提供原子操作的实现,基于 C++0x 草案标准指定的接口。它旨在使转换到 std::atomic 变得容易,并提供一种使使用此 C++0x 功能的代码可在旧系统上编译的方法。
它显然还不是 Boost 的一部分,但你可以在这里查看评论线程:http: //lists.boost.org/Archives/boost/2009/12/160195.php
Boost.Atomic 现在是一种我认为称之为发布的形式。它支持“真正的”原子变量:
- gcc/x86,32 位(在 Linux、FreeBSD 上测试)
- gcc/x86,64 位(在 Linux 上测试)
- gcc/powerpc32(在 Linux、Mac OS X 上测试)
- gcc/powerpc64(未经测试)
- 通用 Win32(在 Win XP 上使用 Visual Studio Express 测试)
对于所有其他人,它会优雅地退回到锁定操作。有适当的快速手册文档,包括一个有希望的说明性示例部分。
作者所说的(在您提供的链接中)是“我认为您可以安全地使用它们,直到一些官方 Boost 库出现”。将接口更改推迟到“当原子函数将出现在 C++0x 中时”。
无论您今天使用什么,您都可能希望在新std::
功能可用时迁移到它。
Boost 的东西通常都很好,看起来它被用于实现已发布的 Boost 库。我也曾多次尝试使用该实现。
我会去的。
您还可以从http://www.ioremap.net/node/224查看 libsync 的灵感,这是相当新的(可能太新了),但它正在 Elliptics Network 中使用,所以它确实得到了(一些?)测试。
它还为您提供了 CAS 旁边的更高级别的原语:RCU(读取复制更新),用于线程之间的无锁同步。
但这取决于您所说的“便携式”是什么意思:它支持架构 x86 和 PPC、操作系统 Linux、FreeBSD、OpenBSD、Solaris 和 MacOSX,但……不支持 Windows。
许可证是 GPL,你可以讨厌或喜欢它。