コード例 #1
0
ファイル: deadlock.c プロジェクト: flavioc/XSB
static void ReclaimDSandMarkReset(th_context *th, VariantSF to, int leader)
{
	CPtr csf = openreg ;
	for(;;)
	{	if( !is_completed(compl_subgoal_ptr(csf)))
		/* Handle early completion */
		{	subg_grabbed(compl_subgoal_ptr(csf)) = TRUE ;
			subg_tid(compl_subgoal_ptr(csf)) = leader ;
    			subg_asf_list_ptr(compl_subgoal_ptr(csf)) = NULL;
    			subg_compl_susp_ptr(compl_subgoal_ptr(csf)) = NULL;
		}
        	if( compl_subgoal_ptr(csf) == to ) 
			break;
                csf = prev_compl_frame(csf) ;
        }
}
コード例 #2
0
ファイル: slgdelay.c プロジェクト: eden/navajoverb
static void handle_unsupported_answer_subst(NODEptr as_leaf)
{
  ASI unsup_asi = Delay(as_leaf);
  VariantSF unsup_subgoal = asi_subgoal(unsup_asi);

#ifdef DEBUG_DELAYVAR
  fprintf(stddbg, ">>>> start handle_unsupported_answer_subst()\n");
#endif

  delete_branch(as_leaf, &subg_ans_root_ptr(unsup_subgoal));
  simplify_pos_unsupported(as_leaf);
  if (is_completed(unsup_subgoal)) {
    if (subgoal_fails(unsup_subgoal)) {
      simplify_neg_fails(unsup_subgoal);
    }
  }
  free(unsup_asi);
}
コード例 #3
0
ファイル: build.c プロジェクト: greatwolf/tundra
static void *
build_worker(void *arg_)
{
	thread_start_arg *arg = (thread_start_arg *) arg_;

	td_job_queue * const queue = arg->queue;
	const int job_id = arg->job_id;

	pthread_mutex_lock(&queue->mutex);

	++queue->thread_count;

	while (!queue->siginfo.flag)
	{
		td_node *node;
		int slot;
		int count = queue->tail - queue->head;

		if (0 == count)
		{
			pthread_cond_wait(&queue->work_avail, &queue->mutex);
			continue;
		}

		slot = (queue->head++) % queue->array_size;

		node = queue->array[slot];
		queue->array[slot] = NULL;

		node->job.flags &= ~TD_JOBF_QUEUED;

		advance_job(queue, node, job_id);

		if (is_completed(node) && is_root(node))
			queue->siginfo.flag = 1;
	}

	--queue->thread_count;
	pthread_mutex_unlock(&queue->mutex);
	pthread_cond_broadcast(&queue->work_avail);

	return NULL;
}
コード例 #4
0
ファイル: slgdelay.c プロジェクト: eden/navajoverb
static void handle_empty_dl_creation(DL dl)
{
  NODEptr as_leaf = dl_asl(dl);
  ASI asi = Delay(as_leaf);
  VariantSF subgoal;

#ifdef DEBUG_DELAYVAR
  fprintf(stddbg, ">>>> start handle_empty_dl_creation()\n");
#endif
  /*
   * Only when `as_leaf' is still a conditional answer can we do
   * remove_dl_from_dl_list(), simplify_pos_unconditional(), and
   * simplify_neg_succeeds() here.
   *
   * If `as_leaf' is already marked UNCONDITIONAL (by
   * unmark_conditional_answer(as_leaf) in simplify_pos_unconditional()),
   * that means this is the second time when `as_leaf' becomes
   * unconditional. So we don't need do anything.  All the DLs have been
   * released in the first time.
   */
  if (is_conditional_answer(as_leaf)) {	/* if it is still conditional */
    remove_dl_from_dl_list(dl, asi);
    subgoal = asi_subgoal(Delay(as_leaf));
#ifdef DEBUG_DELAYVAR
    xsb_dbgmsg((LOG_DEBUG, ">>>> the subgoal is:"));
    dbg_print_subgoal(LOG_DEBUG,stddbg, subgoal); 
    xsb_dbgmsg((LOG_DEBUG, "\n"));
#endif
    /*
     * simplify_pos_unconditional(as_leaf) will release all other DLs for
     * as_leaf, and mark as_leaf as UNCONDITIONAL.
     */
    simplify_pos_unconditional(as_leaf);
    /*-- perform early completion if necessary; please preserve invariants --*/
    if (!is_completed(subgoal) && most_general_answer(as_leaf)) {
      perform_early_completion(subgoal, subg_cp_ptr(subgoal));
      subg_compl_susp_ptr(subgoal) = NULL;
    }
    simplify_neg_succeeds(subgoal);
  }
}
コード例 #5
0
static struct task_struct* psnedf_schedule(struct task_struct * prev)
{
	psnedf_domain_t* 	pedf = local_pedf;
	rt_domain_t*		edf  = &pedf->domain;
	struct task_struct*	next;

	int 			out_of_time, sleep, preempt,
				np, exists, blocks, resched;

	raw_readyq_lock(&pedf->slock);

	/* sanity checking
	 * differently from gedf, when a task exits (dead)
	 * pedf->schedule may be null and prev _is_ realtime
	 */
	BUG_ON(pedf->scheduled && pedf->scheduled != prev);
	BUG_ON(pedf->scheduled && !is_realtime(prev));

	/* (0) Determine state */
	exists      = pedf->scheduled != NULL;
	blocks      = exists && !is_running(pedf->scheduled);
	out_of_time = exists &&
				  budget_enforced(pedf->scheduled) &&
				  bt_flag_is_set(pedf->scheduled, BTF_BUDGET_EXHAUSTED);
	np 	    = exists && is_np(pedf->scheduled);
	sleep	    = exists && is_completed(pedf->scheduled);
	preempt     = edf_preemption_needed(edf, prev);

	/* If we need to preempt do so.
	 * The following checks set resched to 1 in case of special
	 * circumstances.
	 */
	resched = preempt;

	/* Do budget stuff */
	if (blocks)
		budget_state_machine(prev,on_blocked);
	else if (sleep)
		budget_state_machine(prev,on_sleep);
	else if (preempt)
		budget_state_machine(prev,on_preempt);

	/* If a task blocks we have no choice but to reschedule.
	 */
	if (blocks)
		resched = 1;

	/* Request a sys_exit_np() call if we would like to preempt but cannot.
	 * Multiple calls to request_exit_np() don't hurt.
	 */
	if (np && (out_of_time || preempt || sleep))
		request_exit_np(pedf->scheduled);

	/* Any task that is preemptable and either exhausts its execution
	 * budget or wants to sleep completes. We may have to reschedule after
	 * this.
	 */
	if (!np && (out_of_time || sleep) && !blocks) {
		job_completion(pedf->scheduled, !sleep);
		resched = 1;
	}

	/* The final scheduling decision. Do we need to switch for some reason?
	 * Switch if we are in RT mode and have no task or if we need to
	 * resched.
	 */
	next = NULL;
	if ((!np || blocks) && (resched || !exists)) {
		/* When preempting a task that does not block, then
		 * re-insert it into either the ready queue or the
		 * release queue (if it completed). requeue() picks
		 * the appropriate queue.
		 */
		if (pedf->scheduled && !blocks)
			requeue(pedf->scheduled, edf);
		next = __take_ready(edf);
	} else
		/* Only override Linux scheduler if we have a real-time task
		 * scheduled that needs to continue.
		 */
		if (exists)
			next = prev;

	if (next) {
		TRACE_TASK(next, "scheduled at %llu\n", litmus_clock());
	} else {
		TRACE("becoming idle at %llu\n", litmus_clock());
	}

	pedf->scheduled = next;
	sched_state_task_picked();
	raw_readyq_unlock(&pedf->slock);

	return next;
}
コード例 #6
0
ファイル: build.c プロジェクト: greatwolf/tundra
static void
advance_job(td_job_queue *queue, td_node *node, int job_id)
{
	td_jobstate state;
	while ((state = node->job.state) < TD_JOB_COMPLETED)
	{
		switch (state)
		{
		case TD_JOB_INITIAL:
			if (node->job.block_count > 0)
			{
				/* enqueue any blocking jobs and transition to the blocked state */
				int i, count, bc = 0;
				td_node **deps = node->deps;
				for (i = 0, count = node->dep_count; i < count; ++i)
				{
					td_node *dep = deps[i];
					if (!is_completed(dep))
					{
						++bc;
						if (!is_queued(dep) && dep->job.state < TD_JOB_BLOCKED)
							enqueue(queue, dep);
					}
				}
				assert(bc == node->job.block_count);
				transition_job(queue, node, TD_JOB_BLOCKED);
				pthread_cond_broadcast(&queue->work_avail);
				return;
			}
			else
			{
				/* nothing is blocking this job, so scan implicit deps immediately */
				transition_job(queue, node, TD_JOB_SCANNING);
			}
			break;

		case TD_JOB_BLOCKED:
			assert(0 == node->job.block_count);
			if (0 == node->job.failed_deps)
				transition_job(queue, node, TD_JOB_SCANNING);
			else
				transition_job(queue, node, TD_JOB_FAILED);
			break;

		case TD_JOB_SCANNING:

			if (0 == scan_implicit_deps(queue, node))
			{
				update_input_signature(queue, node);

				if (is_up_to_date(queue, node))
					transition_job(queue, node, TD_JOB_UPTODATE);
				else
					transition_job(queue, node, TD_JOB_RUNNING);
			}
			else
			{
				/* implicit dependency scanning failed */
				transition_job(queue, node, TD_JOB_FAILED);
			}
			break;

		case TD_JOB_RUNNING:
			if (0 != run_job(queue, node, job_id))
				transition_job(queue, node, TD_JOB_FAILED);
			else
				transition_job(queue, node, TD_JOB_COMPLETED);
			break;

		default:
			assert(0);
			td_croak("can't get here");
			break;
		}
	}

	if (is_completed(node))
	{
		int qcount = 0;
		td_job_chain *chain = node->job.pending_jobs;

		if (td_debug_check(queue->engine, TD_DEBUG_QUEUE))
			printf("%s completed - enqueing blocked jobs\n", node->annotation);

		/* unblock all jobs that are waiting for this job and enqueue them */
		while (chain)
		{
			td_node *n = chain->node;

			if (is_failed(node))
				n->job.failed_deps++;

			/* nodes blocked on this node can't be completed yet */
			assert(!is_completed(n));

			if (0 == --n->job.block_count)
			{
				if (!is_queued(n))
					enqueue(queue, n);
				++qcount;
			}
			chain = chain->next;
		}

		if (1 < qcount)
			pthread_cond_broadcast(&queue->work_avail);
		else if (1 == qcount)
			pthread_cond_signal(&queue->work_avail);
	}
}
コード例 #7
0
static struct task_struct* demo_schedule(struct task_struct * prev)
{
        struct demo_cpu_state *local_state = local_cpu_state();

        /* next == NULL means "schedule background work". */
        struct task_struct *next = NULL;

        /* prev's task state */
        int exists, out_of_time, job_completed, self_suspends, preempt, resched;

        raw_spin_lock(&local_state->local_queues.ready_lock);

        BUG_ON(local_state->scheduled && local_state->scheduled != prev);
        BUG_ON(local_state->scheduled && !is_realtime(prev));

        exists = local_state->scheduled != NULL;
        self_suspends = exists && !is_current_running();
        out_of_time = exists && budget_enforced(prev) && budget_exhausted(prev);
        job_completed = exists && is_completed(prev);

        /* preempt is true if task `prev` has lower priority than something on
         * the ready queue. */
        preempt = edf_preemption_needed(&local_state->local_queues, prev);

        /* check all conditions that make us reschedule */
        resched = preempt;

        /* if `prev` suspends, it CANNOT be scheduled anymore => reschedule */
        if (self_suspends) {
                resched = 1;
        }

        /* also check for (in-)voluntary job completions */
        if (out_of_time || job_completed) {
                demo_job_completion(prev, out_of_time);
                resched = 1;
        }

        if (resched) {
                /* First check if the previous task goes back onto the ready
                 * queue, which it does if it did not self_suspend.
                 */
                if (exists && !self_suspends) {
                        demo_requeue(prev, local_state);
                }
                next = __take_ready(&local_state->local_queues);
        } else {
                /* No preemption is required. */
                next = local_state->scheduled;
        }

        local_state->scheduled = next;
        if (exists && prev != next) {
                TRACE_TASK(prev, "descheduled.\n");
        }
        if (next) {
                TRACE_TASK(next, "scheduled.\n");
        }

        /* This mandatory. It triggers a transition in the LITMUS^RT remote
         * preemption state machine. Call this AFTER the plugin has made a local
         * scheduling decision.
         */
        sched_state_task_picked();

        raw_spin_unlock(&local_state->local_queues.ready_lock);
        return next;
}
コード例 #8
0
ファイル: hanoi.c プロジェクト: MkPereira/gcompris
/* ==================================== */
static gint
item_event(GooCanvasItem *item,
	   GooCanvasItem *target,
	   GdkEvent *event,
	   PieceItem *data)
{
  double item_x, item_y;

  if(!gcomprisBoard)
    return FALSE;

  if(board_paused)
    return FALSE;

  if(data && !data->on_top)
    return FALSE;

  switch (event->type)
    {
    case GDK_ENTER_NOTIFY:
      g_object_set(item,
		   "stroke-color", "white",
		   "line-width", (double)3,
		   NULL);
      break;
    case GDK_LEAVE_NOTIFY:
      g_object_set(item,
		   "stroke-color", "black",
		   "line-width", (double)1,
		   NULL);
      break;
    case GDK_BUTTON_PRESS:
      switch(event->button.button)
	{
	case 1:
	  gc_sound_play_ogg ("sounds/bleep.wav", NULL);
	  gc_drag_offset_save(event);
	  goo_canvas_item_raise(data->group, NULL);
	  break;
	}
      break;

    case GDK_MOTION_NOTIFY:
      gc_drag_item_move(event, data->group);
      break;

    case GDK_BUTTON_RELEASE:
	{
	  gint i;
	  gint tmpi, tmpj;
	  double tmpx, tmpy;
	  PieceItem *piece_src;
	  PieceItem *piece_dst;
	  gint col = 0, line;

	  item_x = event->button.x;
	  item_y = event->button.y;
	  goo_canvas_convert_from_item_space(goo_canvas_item_get_canvas(item),
					     item,
					     &item_x, &item_y);

	  /* Search the column (x) where this item is ungrabbed */
	  for(i=0; i<=number_of_item_x; i++)
	    if(position[i][0]->x   < item_x &&
	       position[i+1][0]->x > item_x)
	      col = i;

	  /* Bad drop / Outside of column area */
	  /* Bad drop / On the same column */
	  if(col<0 || col > number_of_item_x || col == data->i)
	    {
	      gc_sound_play_ogg ("sounds/eraser2.wav", NULL);

	      /* Return to the original position */
	      gc_item_absolute_move (data->group, data->x , data->y);
	      return FALSE;
	    }


	  /* Now search the free line (y) */
	  line = number_of_item_y;
	  for(i=number_of_item_y-1; i>=0; i--)
	    if(position[col][i]->color == -1)
	      line = i;

	  /* Bad drop / Too many pieces here */
	  if(line >= number_of_item_y)
	    {
	      gc_sound_play_ogg ("sounds/eraser2.wav", NULL);

	      /* Return to the original position */
	      gc_item_absolute_move (data->group, data->x , data->y);

	      return FALSE;
	    }

	  /* Update ontop values for the piece under the grabbed one */
	  if(data->j>0)
	    position[data->i][data->j-1]->on_top = TRUE;

	  /* Update ontop values for the piece under the ungrabbed one */
	  if(line>0)
	    position[col][line-1]->on_top = FALSE;

	  /* Move the piece */
	  piece_dst = position[col][line];
	  piece_src = data;
	  gc_item_absolute_move (data->group, piece_dst->x , piece_dst->y);

	  gc_sound_play_ogg ("sounds/scroll.wav", NULL);

	  /* Swap values in the pieces */
	  tmpx    = data->x;
	  tmpy    = data->y;
	  piece_src->x = piece_dst->x;
	  piece_src->y = piece_dst->y;
	  piece_dst->x = tmpx;
	  piece_dst->y = tmpy;

	  tmpi    = data->i;
	  tmpj    = data->j;
	  position[tmpi][tmpj]->i = piece_dst->i;
	  position[tmpi][tmpj]->j = piece_dst->j;
	  piece_dst->i  = tmpi;
	  piece_dst->j  = tmpj;

	  position[piece_src->i][piece_src->j] = piece_src;
	  position[piece_dst->i][piece_dst->j] = piece_dst;

	  //	  dump_solution();
	  if(is_completed())
	    {
	      gamewon = TRUE;
	      hanoi_destroy_all_items();
	      gc_bonus_display(gamewon, GC_BONUS_SMILEY);
	    }
	}
      break;

    default:
      break;
    }


  return FALSE;
}