将结构传递给 gcc 内置函数以进行原子访问
pass a structure to gcc built-ins for atomic accesses
我有两个结构如下:
template <class T>
struct pointer_t
{
T *ptr;
uintptr_t tag;
};
template <class T>
struct Node
{
T data;
pointer_t<Node<T> > next;
};
现在我想将 pointer_t<Node<T> > newNext
传递给 __sync_bool_compare_and_swap()
函数。根据我传递的函数原型:
__sync_bool_compare_and_swap((unsigned long*) &newTail.ptr->next, oldNext, newNext)
问题是,如果我不将 newNext
转换为 unsigned long
,我将得到:
error: ‘struct pointer_t<Node<int> >’ used where a ‘long unsigned int’ was expected
if ( __sync_bool_compare_and_swap((unsigned long*) &newTail.ptr->next, newNext, newNext) )
如果我将它转换为 unsigned long 那么:
if ( __sync_bool_compare_and_swap((unsigned long*) &newTail.ptr->next, (unsigned long) oldNext, (unsigned long) newNext) )
我会得到:
error: ‘struct pointer_t<Node<int> >’ used where a ‘long unsigned int’ was expected.
谁能给我解释一下,我可以将 __sync_bool_compare_and_swap 与这两个结构一起使用吗?
谢谢
#include <iostream>
#include <bitset>
using namespace std;
template <class T>
struct pointer_t
{
T *ptr;
uintptr_t tag;
};
template <class T>
struct Node
{
T data;
pointer_t<Node<T> >* next;
};
int main()
{
Node<int> *newTail = new Node<int>();
pointer_t<Node<int> > *oldNext = newTail->next;
Node<int> *newNext = new Node<int>();
pointer_t<Node<int> >* newNextPtr = new pointer_t<Node<int> >();
newNextPtr->ptr=newNext;
if ( __sync_bool_compare_and_swap(&newTail->next, oldNext, newNextPtr)) {
std::cout<<"Gotcha!\n";
}
}
这并不能真正解决您的指针标记问题。如果你想实现指针标记,只需从指针中窃取一些未使用的位并设置这些位来标记指针,然后取消设置它们以重置指针。不要忘记在取消引用之前取消标记这些位。
#define get_markedness(p) (((ptr_int) (p)) & 3)
#define get_unmarked_reference(p) ((void *) (((ptr_int) (p)) & (~3)))
#define get_marked_reference(p,m) ((void *) (((ptr_int) (p)) | m))
如果你觉得指针标记很有趣,你可以看看下面的链接
stealing bits from a pointer
http://concurrencyfreaks.blogspot.se/2014/03/harriss-linked-list.html
我有两个结构如下:
template <class T>
struct pointer_t
{
T *ptr;
uintptr_t tag;
};
template <class T>
struct Node
{
T data;
pointer_t<Node<T> > next;
};
现在我想将 pointer_t<Node<T> > newNext
传递给 __sync_bool_compare_and_swap()
函数。根据我传递的函数原型:
__sync_bool_compare_and_swap((unsigned long*) &newTail.ptr->next, oldNext, newNext)
问题是,如果我不将 newNext
转换为 unsigned long
,我将得到:
error: ‘struct pointer_t<Node<int> >’ used where a ‘long unsigned int’ was expected
if ( __sync_bool_compare_and_swap((unsigned long*) &newTail.ptr->next, newNext, newNext) )
如果我将它转换为 unsigned long 那么:
if ( __sync_bool_compare_and_swap((unsigned long*) &newTail.ptr->next, (unsigned long) oldNext, (unsigned long) newNext) )
我会得到:
error: ‘struct pointer_t<Node<int> >’ used where a ‘long unsigned int’ was expected.
谁能给我解释一下,我可以将 __sync_bool_compare_and_swap 与这两个结构一起使用吗?
谢谢
#include <iostream>
#include <bitset>
using namespace std;
template <class T>
struct pointer_t
{
T *ptr;
uintptr_t tag;
};
template <class T>
struct Node
{
T data;
pointer_t<Node<T> >* next;
};
int main()
{
Node<int> *newTail = new Node<int>();
pointer_t<Node<int> > *oldNext = newTail->next;
Node<int> *newNext = new Node<int>();
pointer_t<Node<int> >* newNextPtr = new pointer_t<Node<int> >();
newNextPtr->ptr=newNext;
if ( __sync_bool_compare_and_swap(&newTail->next, oldNext, newNextPtr)) {
std::cout<<"Gotcha!\n";
}
}
这并不能真正解决您的指针标记问题。如果你想实现指针标记,只需从指针中窃取一些未使用的位并设置这些位来标记指针,然后取消设置它们以重置指针。不要忘记在取消引用之前取消标记这些位。
#define get_markedness(p) (((ptr_int) (p)) & 3)
#define get_unmarked_reference(p) ((void *) (((ptr_int) (p)) & (~3)))
#define get_marked_reference(p,m) ((void *) (((ptr_int) (p)) | m))
如果你觉得指针标记很有趣,你可以看看下面的链接
stealing bits from a pointer
http://concurrencyfreaks.blogspot.se/2014/03/harriss-linked-list.html