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 );
}
Example #4
0
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;
}