Пример #1
0
void queueEnqUC(Queue *queue, void* element) {
	LOG_PROLOG();
	QueueElement *queueElement = createNode(element);
	queue->tail->next = queueElement;
	queue->tail = queue->tail->next;
	LOG_EPILOG();
}
Пример #2
0
void* stackPopOther(Stack* stack, int threadIndex)
{
	LOG_PROLOG();
	void *ptr = NULL;if (stack->top->atomicRef->reference == NULL) {
		ptr = NULL;
	}
	else {
		ReferenceIntegerPair *oldTop = setHazardPointer(globalHPStructure, threadIndex, stack->top->atomicRef);
		StackElement *copy = (StackElement*)(oldTop->reference);
		StackElement *nextTopReference = ((StackElement*)(oldTop->reference))->next;
		if (nextTopReference == NULL) {
			clearHazardPointer(globalHPStructure, threadIndex);
			ptr = NULL;
		}
		else if (compareAndSet(stack->top, oldTop->reference, ((StackElement*)oldTop->reference)->next, oldTop->integer, (oldTop->integer + 1), threadIndex)) {
			void* poppedItem = ((StackElement*)oldTop->reference)->value;
			LOG_INFO("stackPopOther: threadid = %d inside CAS \n", threadIndex);
			my_free(copy);
			ptr = poppedItem;
		}
		else
		{
			LOG_INFO("stackPopOther: CAS failed\n");
			ptr = NULL;
		}
	}
	LOG_EPILOG();
	return ptr;
}
Пример #3
0
void circularQueueFree(CircularQueue *queue) {
	LOG_PROLOG();

	if (queue != NULL) {
		CircularQueueElement *ptr = NULL;
		while(!isCircularQueueEmpty(queue)) {
			ptr = circularQueueDeq(queue);
			if (ptr != NULL) {
				if (ptr->value != NULL) {
					my_free(ptr->value);
					ptr->value = NULL;
				}

				my_free(ptr);
				ptr = NULL;
			} else {
				LOG_ERROR("Trying to free NULL pointer popped from circular queue");
			}
		}

		my_free(queue);
		queue = NULL;
	} else {
		LOG_ERROR("Trying to free NULL pointer");
	}

	LOG_EPILOG();
}
Пример #4
0
void wf_enqueue(wf_queue_head_t *q, wf_queue_node_t* node, wf_queue_op_head_t* op_desc, int thread_id) {
	LOG_PROLOG();

	long phase = max_phase(op_desc) + 1;
	stamped_ref_t *old_stamped_ref = *(op_desc->ref_mem.ops + thread_id);
	stamped_ref_t *reserve_stamped_ref = *(op_desc->ref_mem.ops_reserve + thread_id);//(stamped_ref_t*)malloc(sizeof(stamped_ref_t));

	wf_queue_op_desc_t *op = *(op_desc->ops_reserve + thread_id);//(wf_queue_op_desc_t*)malloc(sizeof(wf_queue_op_desc_t));
	op->phase = phase;

	node->enq_tid = thread_id;
	node->next->ref = NULL;

	op->node = node;
	op->pending = 1;
	op->enqueue = 1;

	reserve_stamped_ref->ref = op;
	reserve_stamped_ref->stamp = old_stamped_ref->stamp;

	*(op_desc->ref_mem.ops_reserve + thread_id) = old_stamped_ref;
	*(op_desc->ops_reserve + thread_id) = old_stamped_ref->ref;

	*(op_desc->ref_mem.ops + thread_id) = reserve_stamped_ref;

	help(q, op_desc, thread_id, phase);
	help_finish_enq(q, op_desc, thread_id);

	LOG_EPILOG();
}
Пример #5
0
void* circularQueueDeq(CircularQueue *queue) {
	LOG_PROLOG();

	void *ptr = NULL;
	if (queue != NULL) {
        if (isCircularQueueEmpty(queue)) {
            LOG_INFO("Empty Circular queue, nothing to dequeue");
        } else {
            ptr = getCircularQueueElement(queue, queue->head)->value;

            getCircularQueueElement(queue, queue->head)->value = NULL;

            if (queue->head == queue->tail) {
                queue->head = queue->tail = -1;
            } else {
                queue->head = (queue->head + 1) % queue->maxNumberOfElements;
            }
        }
	} else {
        LOG_ERROR("Invalid queue!");
	}

	LOG_EPILOG();
	return ptr;
}
Пример #6
0
void* stackPopOwner(Stack* stack, int threadId)
{
	LOG_PROLOG();
	void *ptr = NULL;
	ReferenceIntegerPair *oldTop = setHazardPointer(globalHPStructure, threadId, stack->top->atomicRef);

	if(stack->top->atomicRef->reference == NULL){
		LOG_INFO("stackPopOwner: stack was empty\n");
		ptr = NULL;
	}
	else {
		void *oldValue = ((StackElement*)oldTop->reference)->value;
		StackElement *copy = (StackElement*)(oldTop->reference);
		StackElement *nextTopReference = ((StackElement*)(oldTop->reference))->next;
		if (compareAndSet(stack->top, oldTop->reference, nextTopReference, oldTop->integer, (oldTop->integer+1), threadId)) {
			my_free(copy);
			ptr = oldValue;
		}
		else {
			//clearHazardPointer(globalHPStructure, threadId);
			LOG_INFO("stackPopOwner: CAS failed");
			ptr = NULL;
		}
	}
	LOG_EPILOG();
	return ptr;
}
Пример #7
0
wf_queue_node_t* wf_dequeue(wf_queue_head_t *q, wf_queue_op_head_t* op_desc, int thread_id) {
	LOG_PROLOG();

	wf_queue_node_t* node = NULL;

	long phase = max_phase(op_desc) + 1;
	stamped_ref_t *old_stamped_ref = *(op_desc->ref_mem.ops + thread_id);
	stamped_ref_t *reserve_stamped_ref = *(op_desc->ref_mem.ops_reserve + thread_id);

	wf_queue_op_desc_t *op = *(op_desc->ops_reserve + thread_id);
	op->phase = phase;
	op->node = NULL;
	op->pending = 1;
	op->enqueue = false;

	reserve_stamped_ref->ref = op;
	reserve_stamped_ref->stamp = old_stamped_ref->stamp;

	*(op_desc->ref_mem.ops_reserve + thread_id) = old_stamped_ref;
	*(op_desc->ops_reserve + thread_id) = old_stamped_ref->ref;

	*(op_desc->ref_mem.ops + thread_id) = reserve_stamped_ref;

	help(q, op_desc, thread_id, phase);
	help_finish_deq(q, op_desc, thread_id);

	node = STAMPED_REF_TO_REF(*(op_desc->ref_mem.ops + thread_id), wf_queue_op_desc_t)->node;
	if (unlikely(node == NULL)) {
		LOG_WARN("Dequeued node is NULL");
	}

	LOG_EPILOG();
	return node;
}
Пример #8
0
CircularQueue* circularQueueCreate(int elementSize, int noOfElements) {
	LOG_PROLOG();

	CircularQueue *queue = (CircularQueue*) my_malloc(sizeof(CircularQueue));
	if (queue != NULL) {
        queue->head = queue->tail = -1;
        queue->elementSize = elementSize;
        queue->maxNumberOfElements = noOfElements;

        queue->baseAddress = (CircularQueueElement*) my_malloc(sizeof(CircularQueueElement) * noOfElements);
        if (queue->baseAddress == NULL) {
            LOG_ERROR("Unable to allocate memory for circular queue elements");
        } else {
            for (int i = 0; i < noOfElements; i++) {
                getCircularQueueElement(queue, i)->value = NULL;
            }
        }

	} else {
        LOG_ERROR("Unable to allocate memory for circular queue");
	}

	LOG_EPILOG();
	return queue;
}
Пример #9
0
void help_enq(wf_queue_head_t* queue, wf_queue_op_head_t* op_desc, int thread_id, int thread_to_help, long phase) {
	LOG_PROLOG();

	while (is_pending(op_desc, phase, thread_to_help)) {
		wf_queue_node_t *last = STAMPED_REF_TO_REF(queue->tail, wf_queue_node_t);
		stamped_ref_t *next = last->next;
		wf_queue_node_t* old_ref_next = STAMPED_REF_TO_REF(next, wf_queue_node_t);
		wf_queue_node_t *new_node = STAMPED_REF_TO_REF(*(op_desc->ref_mem.ops + thread_to_help), wf_queue_op_desc_t)->node;

		uint32_t old_stamp = last->next->stamp;
		uint32_t new_stamp = (old_stamp + 1);
		if (last == STAMPED_REF_TO_REF(queue->tail, wf_queue_node_t)) {
			if (STAMPED_REF_TO_REF(last->next, wf_queue_node_t) == NULL) {
				if (is_pending(op_desc, phase, thread_to_help)) {
					stamped_ref_t* node_new_stamped_ref = *(op_desc->ref_mem.next_reserve + thread_id);//(stamped_ref_t*)malloc(sizeof(stamped_ref_t));
					node_new_stamped_ref->ref = new_node;
					node_new_stamped_ref->stamp += new_stamp;
					if (CAS_COND1(STAMPED_REF_TO_REF(queue->tail, wf_queue_node_t)->next, next, old_ref_next, old_stamp, node_new_stamped_ref)) {
						if (CAS_COND2(STAMPED_REF_TO_REF(queue->tail, wf_queue_node_t)->next, next, old_ref_next, old_stamp, node_new_stamped_ref)) {
							help_finish_enq(queue, op_desc, thread_id);
							return;
						} else if (CAS_COND3(STAMPED_REF_TO_REF(queue->tail, wf_queue_node_t)->next, next, old_ref_next, old_stamp, node_new_stamped_ref)) {
							*(op_desc->ref_mem.next_reserve + thread_id) = next; // Recycle stamped reference
							help_finish_enq(queue, op_desc, thread_id);
							return;
						}
					}
				}
			} else {
				help_finish_enq(queue, op_desc, thread_id);
			}
		}
	}
	LOG_EPILOG();
}
Пример #10
0
void stackFree(Stack *stack)
{
	LOG_PROLOG();
	if (stack != NULL) {
		while (!STACK_IS_EMPTY(stack)) {
			void *element = stackPop(stack);
			if (element != NULL) {
				my_free(element);
				element = NULL;
			}
			else {
				LOG_ERROR("Trying to free NULL pointer popped from stack");
			}
		}
		freeAtomicStampedReference(stack->top);
		stack->elementSize = 0;
		stack->numberOfElements = 0;
		my_free(stack->top);
		stack->top = NULL;
	}
	else {
		LOG_ERROR("Trying to free NULL stack pointer");
	}
	LOG_EPILOG();
}
Пример #11
0
void destroyWaitFreePool() {
	LOG_PROLOG();
	if (memory != NULL) {
		destroyFullPool(memory->fullPool);
		LOG_INFO("FullPool successfully destroyed");
		destroyFreePoolUC(memory->freePoolUC);
		LOG_INFO("FreePoolUC successfully destroyed");
		destroyFreePoolC(memory->freePoolC);
		LOG_INFO("FreePoolC successfully destroyed");
		destroyLocalPool(memory->localPool);
		LOG_INFO("LocalPool successfully destroyed");
		destroySharedQueuePools(memory->sharedQueuePools);
		LOG_INFO("SharedQueuePools successfully destroyed");

		if (memory->announce != NULL) {
			if (memory->announce->helpers != NULL) {
				for (int i = 0; i < memory->n; i++) {
					freeAtomicStampedReference(getHelperEntry(i));
				}
				my_free(memory->announce->helpers);
				memory->announce->helpers = NULL;
			}
			else {
				LOG_ERROR("Trying to free helper pointer of announce array which is a NULL pointer");
			}
			my_free(memory->announce);
			memory->announce = NULL;
		}
		else {
			LOG_ERROR("Trying to free announce array which is a NULL pointer");
		}
		LOG_INFO("Announce array successfully destroyed");

		if (memory->info != NULL) {
			if (memory->info->donors != NULL) {
				my_free(memory->info->donors);
				memory->info->donors = NULL;
			}
			else {
				LOG_ERROR("Trying to free donor pointer of info array which is a NULL pointer");
			}
			memory->info->numOfDonors = 0;
			my_free(memory->info);
			memory->info = NULL;
		}
		else {
			LOG_ERROR("Trying to free info array which is a NULL pointer");
		}
		LOG_INFO("Info array successfully destroyed");

		my_free(memory);
		memory = NULL;
	}
	else {
		LOG_ERROR("Trying to free memory pointer which is a NULL pointer");
	}

	LOG_EPILOG();
}
Пример #12
0
bool has_empty_block(page_t* ptr) {
	LOG_PROLOG();

	bool result = (find_first_empty_block(ptr) != -1);

	LOG_EPILOG();
	return result;
}
Пример #13
0
void freeNode(QueueElement* element) {
	LOG_PROLOG();
	element->value = NULL;
	element->next = NULL;
	my_free(element);
	element = NULL;
	LOG_EPILOG();
}
Пример #14
0
void queueCreate(Queue *queue, int elementSize) {
	LOG_PROLOG();
	queue->head = createNode(NULL);
	queue->tail = queue->head;
	//printf("queueCreate: queuePtr = %u, headPtr = %u, TailPtr = %u \n", queue, queue->head, queue->tail);
	queue->elementSize  = elementSize;
	LOG_EPILOG();
}
Пример #15
0
bool is_pending(wf_queue_op_head_t* op_desc, long phase, int thread_id) {
	LOG_PROLOG();

	wf_queue_op_desc_t* op_tmp = STAMPED_REF_TO_REF(*(op_desc->ref_mem.ops + thread_id), wf_queue_op_desc_t);

	LOG_EPILOG();
	return ((op_tmp->pending == 1) && (op_tmp->phase <= phase));
}
Пример #16
0
QueueElement* createNode(void *value) {
	LOG_PROLOG();
	//printf("createNode blk ptr = %u\n", value);
	QueueElement *element = (QueueElement*) my_malloc(sizeof(QueueElement));
	element->value = value;
	element->next = NULL;
	LOG_EPILOG();
	return element;
}
Пример #17
0
// used only for testing
wf_queue_node_t* create_wf_queue_node() {
	LOG_PROLOG();

	wf_queue_node_t* node = (wf_queue_node_t*)malloc(sizeof(wf_queue_node_t));
	init_wf_queue_node(node);

	LOG_EPILOG();
	return node;
}
Пример #18
0
void lfree(void* ptr) {

    LOG_PROLOG();
    lpage_t *lptr = get_lptr(ptr);
    assert(is_lpage_aligned(lptr));
    uint32_t num_pages = get_num_pages(lptr);
    munmap(ptr, num_pages * PAGE_SIZE);
    LOG_EPILOG();
}
Пример #19
0
void free_block(void *block_ptr) {
	LOG_PROLOG();

	mem_block_header_t *block_header = (mem_block_header_t*)((char*)block_ptr - sizeof(mem_block_header_t));
	page_t* page_ptr = (page_t*)((char*)block_header - block_header->byte_offset);
	page_ptr->header.block_flags[block_header->idx] = BLOCK_EMPTY;

	LOG_EPILOG();
}
Пример #20
0
void stackCreate(Stack *stack, int elementSize)
{
	LOG_PROLOG();
	stack->top = (AtomicStampedReference*) my_malloc(sizeof(AtomicStampedReference));
	createAtomicStampedReference(stack->top, NULL, 0);
	stack->elementSize = elementSize;
	stack->numberOfElements = 0;
	LOG_EPILOG();
}
Пример #21
0
bool stackPushOther(Stack *stack, void* element, ReferenceIntegerPair* oldTop, int threadId)
{
	LOG_PROLOG();
	StackElement *node = (StackElement*)my_malloc(sizeof(StackElement));
	node->value = element;
	node->next = (StackElement*)stack->top->atomicRef->reference;
	bool flag = compareAndSet(stack->top, NULL, node, oldTop->integer, (oldTop->integer + 1), threadId);
	LOG_EPILOG();
	return flag;
}
Пример #22
0
bool stackPush(Stack *stack, void* element) {
	LOG_PROLOG();
	StackElement *node = (StackElement*)my_malloc(sizeof(StackElement));
	node->value = element;
	node->next = (StackElement*)stack->top->atomicRef->reference;

	stack->top->atomicRef->reference = node;
	stack->numberOfElements++;
	LOG_EPILOG();
	return true;
}
Пример #23
0
void init_wf_queue_node(wf_queue_node_t* node) {
	LOG_PROLOG();

	node->next = (stamped_ref_t*)malloc(sizeof(stamped_ref_t)); // called whne page is created; pages are created when we ask OS
	node->next->stamp = 0;
	node->next->ref = NULL;
	node->enq_tid = -1;
	node->deq_tid = -1;

	LOG_EPILOG();
}
Пример #24
0
wf_queue_op_head_t* create_queue_op_desc(int num_threads) {
	LOG_PROLOG();

	wf_queue_op_head_t* op_desc = (wf_queue_op_head_t*)malloc(sizeof(wf_queue_op_head_t));
	op_desc->num_threads = num_threads;
	op_desc->ops = malloc(num_threads * sizeof(wf_queue_op_desc_t*));
	op_desc->ops_reserve = malloc(num_threads * sizeof(wf_queue_op_desc_t*));

	wf_queue_op_desc_t* ops = (wf_queue_op_desc_t*)malloc(2 * num_threads * sizeof(wf_queue_op_desc_t));
	wf_queue_op_desc_t* ops_reserve = (ops + num_threads);
	int thread = 0;
	for (thread = 0; thread < num_threads; ++thread) {
		*(op_desc->ops + thread) = (ops + thread);
		*(op_desc->ops_reserve + thread) = (ops_reserve + thread);
		(ops + thread)->phase = -1;
		(ops + thread)->enqueue = 0;
		(ops + thread)->pending = 0;
		(ops + thread)->node = NULL;
	}

	op_desc->ref_mem.next_reserve = malloc(num_threads * sizeof(stamped_ref_t*));
	op_desc->ref_mem.head_reserve = malloc(num_threads * sizeof(stamped_ref_t*));
	op_desc->ref_mem.tail_reserve = malloc(num_threads * sizeof(stamped_ref_t*));
	op_desc->ref_mem.ops = malloc(num_threads * sizeof(stamped_ref_t*));
	op_desc->ref_mem.ops_reserve = malloc(num_threads * sizeof(stamped_ref_t*));

	stamped_ref_t* tmp = (stamped_ref_t*)malloc(REF_MEM_COUNT * num_threads * sizeof(stamped_ref_t));
	for (thread = 0; thread < num_threads; ++thread) {
		*(op_desc->ref_mem.next_reserve + thread) = (tmp + thread + num_threads*(REF_MEM_NEXT_RES));
		(*(op_desc->ref_mem.next_reserve + thread))->stamp = 0;
		(*(op_desc->ref_mem.next_reserve + thread))->ref = NULL;

		*(op_desc->ref_mem.head_reserve + thread) = (tmp + thread + num_threads*(REF_MEM_HEAD_RES));
		(*(op_desc->ref_mem.head_reserve + thread))->stamp = 0;
		(*(op_desc->ref_mem.head_reserve + thread))->ref = NULL;

		*(op_desc->ref_mem.tail_reserve + thread) = (tmp + thread + num_threads*(REF_MEM_TAIL_RES));
		(*(op_desc->ref_mem.tail_reserve + thread))->stamp = 0;
		(*(op_desc->ref_mem.tail_reserve + thread))->ref = NULL;

		*(op_desc->ref_mem.ops + thread) = (tmp + thread + num_threads*REF_MEM_OPS);
		(*(op_desc->ref_mem.ops + thread))->stamp = 0;
		(*(op_desc->ref_mem.ops + thread))->ref = *(op_desc->ops + thread);

		*(op_desc->ref_mem.ops_reserve + thread) = (tmp + thread + num_threads*(REF_MEM_OPS_RES));
		(*(op_desc->ref_mem.ops_reserve + thread))->stamp = 0;
		(*(op_desc->ref_mem.ops_reserve + thread))->ref = NULL;
	}

	LOG_EPILOG();
	return op_desc;
}
Пример #25
0
int circularQueueGetElementSize(CircularQueue *queue){
    LOG_PROLOG();

	int size = 0;
	if (queue != NULL) {
        size = queue->elementSize;
	} else {
        LOG_ERROR("Invalid queue!");
	}

	LOG_EPILOG();
	return size;
}
Пример #26
0
int circularQueueGetMaxNumberOfElements(CircularQueue *queue){
    LOG_PROLOG();

	int numElementes = 0;
	if (queue != NULL) {
        numElementes = queue->maxNumberOfElements;
	} else {
        LOG_ERROR("Invalid queue!");
	}

	LOG_EPILOG();
	return numElementes;
}
Пример #27
0
wf_queue_head_t* create_wf_queue(wf_queue_node_t* sentinel) {
	LOG_PROLOG();

	wf_queue_head_t* queue = (wf_queue_head_t*)malloc(sizeof(wf_queue_head_t));
	queue->head = (stamped_ref_t*)malloc(sizeof(stamped_ref_t));
	queue->head->ref = sentinel;
	queue->head->stamp = 0;
	queue->tail = (stamped_ref_t*)malloc(sizeof(stamped_ref_t));
	queue->tail->ref = sentinel;
	queue->tail->stamp = 0;

	LOG_EPILOG();
	return queue;
}
Пример #28
0
bool stackPushOwner(Stack *stack, void* element, int threadId)
{
	LOG_PROLOG();
	StackElement *node = (StackElement*)my_malloc(sizeof(StackElement));
	node->value = element;
	node->next = (StackElement*)stack->top->atomicRef->reference;
	//LOG_INFO("stackPushOwner before setting HP\n");
	LOG_INFO("global Structure is %u", globalHPStructure);
	ReferenceIntegerPair *oldTop = setHazardPointer(globalHPStructure, threadId, stack->top->atomicRef);

	bool flag = compareAndSet(stack->top, oldTop->reference, node, oldTop->integer, (oldTop->integer + 1), threadId);
	LOG_EPILOG();
	return flag;
}
Пример #29
0
bool isCircularQueueFull(CircularQueue *queue) {
	LOG_PROLOG();
	bool flag = false;
	if (queue != NULL) {
        if (((queue->tail + 1) % queue->maxNumberOfElements) == queue->head) {
            flag = true;
        }
	} else {
        LOG_ERROR("Invalid queue!");
	}

	LOG_EPILOG();
	return flag;
}
Пример #30
0
bool donate(int threadId, Chunk *chunk) {
	LOG_PROLOG();
	//LOG_INFO("donate: threadID %d\n", threadId);
	int i = (getDonorEntry(threadId)->lastDonated + 1) % (memory->n);
	bool *tempBoolObj;
	assert(globalHPStructure->topPointers[threadId] == 0);
	do {
		LOG_INFO("donate: trying to donate to %d", i);
		ReferenceIntegerPair *announceOfThreadToBeHelped = setHazardPointer(globalHPStructure, threadId, getHelperEntry(i)->atomicRef);
		ReferenceIntegerPair *oldTop = setHazardPointer(globalHPStructure, threadId, GET_STACK_THREAD(memory->fullPool, i)->stack->top->atomicRef);
		assert(globalHPStructure->topPointers[threadId] == 2);
	//	int oldTS = announceOfThreadToBeHelped->integer;
		if ((*(bool*)announceOfThreadToBeHelped->reference == true) && (GET_STACK_THREAD(memory->fullPool, i)->stack->top->atomicRef->reference == NULL) && (getHelperEntry(i)->atomicRef->integer == announceOfThreadToBeHelped->integer)) {
			LOG_INFO("donate: %d needed help", i);
			if (putInOtherFullPool(memory->fullPool, i, chunk, oldTop, threadId)) {
				assert(globalHPStructure->topPointers[threadId] == 1);
				LOG_INFO("donate: successfully donated to %d", i);
				tempBoolObj = (bool*)my_malloc(sizeof(bool));
				*tempBoolObj = false;
				if(!compareAndSet(getHelperEntry(i),announceOfThreadToBeHelped->reference, tempBoolObj, announceOfThreadToBeHelped->integer, (announceOfThreadToBeHelped->integer + 1), threadId)) {
					//clearHazardPointer(globalHPStructure, threadId);
					my_free(tempBoolObj);
				}
				assert(globalHPStructure->topPointers[threadId] == 0);
				getDonorEntry(threadId)->lastDonated = i;
				LOG_EPILOG();
				return true;
			}
			LOG_INFO("donate: donation to %d failed: someone else helped", i);
			//getHelperEntry(i)->compareAndSet(...);
			tempBoolObj = (bool*)my_malloc(sizeof(bool));
			*tempBoolObj = false;
			if (!compareAndSet(getHelperEntry(i),announceOfThreadToBeHelped->reference, tempBoolObj, announceOfThreadToBeHelped->integer, (announceOfThreadToBeHelped->integer + 1), threadId)) {
				//clearHazardPointer(globalHPStructure, threadId);
				my_free(tempBoolObj);
			}
			assert(globalHPStructure->topPointers[threadId] == 0);
		}
		else {
			clearHazardPointer(globalHPStructure, threadId);
			clearHazardPointer(globalHPStructure, threadId);
			LOG_INFO("donate: clearing HP of thread. Donation was not needed");
		}
		i = (i + 1) % (memory->n);
		assert(globalHPStructure->topPointers[threadId] == 0);
	} while(i != (getDonorEntry(threadId)->lastDonated + 1) % (memory->n));
	LOG_EPILOG();
	return false;
}