view Paper/src/SynchronizedQueue.c @ 33:c1323b737cfd

...
author matac42 <matac@cr.ie.u-ryukyu.ac.jp>
date Thu, 18 Jan 2024 19:37:19 +0900
parents c8151a82f313
children
line wrap: on
line source

#include "../context.h"
// include "Queue.h"
// include "Atomic.h"

#include <stdio.h>

Queue* createSynchronizedQueue(struct Context* context) {
    struct Queue* queue = &ALLOCATE(context, Queue)->Queue;
    struct SynchronizedQueue* synchronizedQueue = &ALLOCATE(context, SynchronizedQueue)->SynchronizedQueue;
    synchronizedQueue->top = &ALLOCATE(context, Element)->Element; // allocate a free node
    synchronizedQueue->top->next = NULL;
    synchronizedQueue->last = synchronizedQueue->top;
    synchronizedQueue->atomic = createAtomicReference(context); // not used
    queue->queue = (union Data*)synchronizedQueue;
    queue->take  = C_takeSynchronizedQueue;
    queue->put  = C_putSynchronizedQueue;
    queue->isEmpty = C_isEmptySynchronizedQueue;
    queue->clear = C_clearSynchronizedQueue;
    return queue;
}


__code putSynchronizedQueue(struct Context *context,struct SynchronizedQueue* queue, union Data* data, enum Code next) {
    Element* element = &ALLOCATE(context, Element)->Element;
    element->data = data;
    element->next = NULL;
    Element* last = queue->last;
    Element* nextElement = last->next;
    if (last != queue->last) {
        goto meta(context, C_putSynchronizedQueue);
    }
    if (nextElement == NULL) {
        struct Atomic* atomic = queue->atomic;
        Gearef(context, Atomic)->atomic = (union Data*) atomic;
        Gearef(context, Atomic)->ptr = (union Data**) &last->next;
        Gearef(context, Atomic)->oldData = (union Data*) nextElement;
        Gearef(context, Atomic)->newData = (union Data*) element;
        Gearef(context, Atomic)->next = next;
        Gearef(context, Atomic)->fail = C_putSynchronizedQueue;
        goto meta(context, atomic->checkAndSet);
    } else {
        struct Atomic* atomic = queue->atomic;
        Gearef(context, Atomic)->atomic = (union Data*) atomic;
        Gearef(context, Atomic)->ptr = (union Data**) &queue->last;
        Gearef(context, Atomic)->oldData = (union Data*) last;
        Gearef(context, Atomic)->newData = (union Data*) nextElement;
        Gearef(context, Atomic)->next = C_putSynchronizedQueue;
        Gearef(context, Atomic)->fail = C_putSynchronizedQueue;
        goto meta(context, atomic->checkAndSet);
    }
}

__code putSynchronizedQueue_stub(struct Context* context) {
	SynchronizedQueue* queue = (SynchronizedQueue*)GearImpl(context, Queue, queue);
	Data* data = Gearef(context, Queue)->data;
	enum Code next = Gearef(context, Queue)->next;
	goto putSynchronizedQueue(context, queue, data, next);
}