比較と交換を使用して c でロック フリー キューを実装するように依頼されましたが、ポインターに関する知識はかなり限られています。
次のコードを使用して、(まだ不完全な) デキューの実装をテストしていますが、ポインター/演算子のアドレスを適切に使用する方法がよくわからないため、無限にループしていると思います。
私はアセンブラについて何も知らないので、この CAS 関数を使用するように与えられました。
long __cdecl compare_exchange(long *flag, long oldvalue, long newvalue)
{
__asm
{
mov ecx, flag
mov eax, oldvalue
mov ebx, newvalue
lock cmpxchg [ecx], ebx
jz iftrue
}
return 0;
iftrue: return 1;
}
私の現在の(関連する)コードは次のとおりです...
typedef struct QueueItem
{
int data;
struct QueueItem* next;
}item;
struct Queue
{
item *head;
item *tail;
}*queue;
int Dequeue()
{
item *head;
do
{
head = queue->head;
if(head == NULL)
return NULL_ITEM;
printf("%d, %d, %d\n", (long *)queue->head, (long)&head, (long)&head->next);
}
while(!compare_exchange((long *)queue->head, (long)&head, (long)&head->next)); // Infinite loop.
return head->data;
}
int main(int argc, char *argv[])
{
item i, j;
queue = (struct Queue *) malloc(sizeof(struct Queue));
// Manually enqueue some data for testing dequeue.
i.data = 5;
j.data = 10;
i.next = &j;
j.next = NULL;
queue->head = &i;
printf("Dequeued: %d\n", Dequeue());
printf("Dequeued: %d\n", Dequeue());
}
do while ループ内で not 演算子を使用する必要がありますか? その演算子を使用しない場合、"Dequeued 5" x2 の出力が得られます。これは、スワップが発生していないことを示しており、not を使用する必要があることを示しています。もしそうなら、どこが間違っていますか?ポインター/アドレス演算子の問題であることにお金をかけます。