void queueEnqUC(Queue *queue, void* element) { LOG_PROLOG(); QueueElement *queueElement = createNode(element); queue->tail->next = queueElement; queue->tail = queue->tail->next; LOG_EPILOG(); }
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; }
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(); }
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(); }
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; }
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; }
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; }
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; }
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(); }
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(); }
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(); }
bool has_empty_block(page_t* ptr) { LOG_PROLOG(); bool result = (find_first_empty_block(ptr) != -1); LOG_EPILOG(); return result; }
void freeNode(QueueElement* element) { LOG_PROLOG(); element->value = NULL; element->next = NULL; my_free(element); element = NULL; LOG_EPILOG(); }
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(); }
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)); }
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; }
// 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; }
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(); }
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(); }
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(); }
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; }
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; }
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(); }
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; }
int circularQueueGetElementSize(CircularQueue *queue){ LOG_PROLOG(); int size = 0; if (queue != NULL) { size = queue->elementSize; } else { LOG_ERROR("Invalid queue!"); } LOG_EPILOG(); return size; }
int circularQueueGetMaxNumberOfElements(CircularQueue *queue){ LOG_PROLOG(); int numElementes = 0; if (queue != NULL) { numElementes = queue->maxNumberOfElements; } else { LOG_ERROR("Invalid queue!"); } LOG_EPILOG(); return numElementes; }
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; }
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; }
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; }
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; }