key_type pq_delete_min( strict_fibonacci_heap *queue ) { if( pq_empty( queue ) ) return 0; key_type key = queue->root->key; strict_fibonacci_node *current, *new_root, *old_root; int i, j; old_root = queue->root; if( old_root->left_child == NULL ) { old_root = queue->root; if( is_active( queue, old_root ) ) convert_to_passive( queue, old_root ); queue->root = NULL; } else { new_root = select_new_root( queue ); remove_from_siblings( queue, new_root ); dequeue_node( queue, new_root ); queue->root = new_root; if( is_active( queue, new_root ) ) convert_to_passive( queue, new_root ); if( is_active( queue, old_root ) ) convert_to_passive( queue, old_root ); while( old_root->left_child != NULL ) link( queue, new_root, old_root->left_child ); for( i = 0; i < 2; i++ ) { current = consume_node( queue ); if( current != NULL ) { for( j = 0; j < 2; j++ ) { if( current->left_child != NULL && !is_active( queue, current->left_child->left ) ) link( queue, new_root, current->left_child->left ); else break; } } } } pq_free_node( queue->map, STRICT_NODE_FIB, old_root ); post_delete_min_reduction( queue ); garbage_collection( queue ); queue->size--; return key; }
int pthread_workqueue_additem_np(pthread_workqueue_t workq, void *(*workitem_func)(void *), void * workitem_arg, pthread_workitem_handle_t * itemhandlep, unsigned int *gencountp) { wq_t *wq = (wq_t *) workq; if(_is_valid_workqueue(wq) &&_wq_configured) { pthread_workitem_handle_t *new_job = calloc(1, sizeof(pthread_workitem_handle_t)); if(new_job == NULL) { return ENOMEM; } else { //Because the attr was guaranteed to be valid (in _is_valid_workqueue), queue should never be NULL dequeue_t *queue = _queue_for_priority(wq->attr.priority); assert(queue != NULL); new_job->workq = workq; new_job->func = workitem_func; new_job->arg = workitem_arg; list_node_t *node = dequeue_node(); if(node == NULL) { free(new_job); return ENOMEM; } pthread_mutex_lock(&_job_queue_mutex); dequeue_append_node(queue, node, new_job); //FIXME: check for success/failure (currently no such checks) psem_up(&_job_semaphore); pthread_mutex_unlock(&_job_queue_mutex); if(psem_peek(&_job_semaphore) >= 0) { //FIXME: we might and likely accidentally will spawn workers unintentinally here _spawn_worker(); } if(itemhandlep != NULL) { *itemhandlep = *new_job; // FIXME: this is just a hack to feel like the spec. } if(gencountp != NULL) { *gencountp = 0; // FIXME: In Apple's implimentation this is used to keep track of how many times a given workitem struct has been used. } } } else{ return EINVAL; } return 0; }
void pq_decrease_key( strict_fibonacci_heap *queue, strict_fibonacci_node *node, key_type new_key ) { strict_fibonacci_node *old_parent = node->parent; node->key = new_key; if( old_parent == NULL || node->key > old_parent->key) return; strict_fibonacci_node *parent, *child; choose_order_pair( node, queue->root, &parent, &child ); link( queue, parent, child ); queue->root = parent; queue->root->parent = NULL; if( parent == node ) { dequeue_node( queue, parent ); enqueue_node( queue, child ); } if( is_active( queue, node ) ) { if( is_active( queue, old_parent ) ) decrease_rank( queue, old_parent ); if( node->type != STRICT_TYPE_ROOT ) convert_active_to_root( queue, node ); } if( is_active( queue, old_parent ) && old_parent->type != STRICT_TYPE_ROOT ) increase_loss( queue, old_parent ); post_decrease_key_reduction( queue ); garbage_collection( queue ); }
int main(void) { /* Declare YOUR variables here ! */ Stack mystack; Queue myqueue; int menu_choice; srand((unsigned int)time(NULL)); if ((myqueue = QUEUEinit(my_destroy)) == NULL) /* Create new queue... */ { printf("\nFatal error - bailing out...!"); QUEUEdestroy(myqueue); exit(-1); } if ((mystack = STACKinit(my_destroy)) == NULL) /* Create new stack... */ { printf("\nFatal error - bailing out...!"); STACKdestroy(mystack); exit(-1); } /* Create and initialize queue and stack... */ enqueue_push_nodes(myqueue, mystack, NR_OF_ITEMS); do { menu_choice = menu(MAIN_MENU_ROW, 0, 6); switch (menu_choice) { case 1: enqueue_node(myqueue); break; case 2: dequeue_node(myqueue); break; case 3: push_node(mystack); break; case 4: pop_node(mystack); break; case 5: dequeue_push_node(myqueue, mystack); break; case 6: print_queue_stack(myqueue, mystack); break; default: final_status(myqueue, mystack); break; } } while (menu_choice); prompt_and_pause("\n\nLet's tidy up (destroy queue/stack)..- Bye!"); STACKdestroy(mystack); QUEUEdestroy(myqueue); return 0; }