示例#1
0
  static inline void
  finish (bool output_fired,
	  bd_t bda,
	  bd_t bdb)
  {
    if (action_.automaton.get () != 0) {
      // We were executing an action of this automaton.

      switch (action_.action->type) {
      case INPUT:
	// We were executing an input.  Move to the next input.
	++input_action_pos_;
	proceed_to_input ();
	// -EEE
	input_action_list_.front ()->output_action.automaton->unlock_execution ();
	finish_output ();
	break;
      case OUTPUT:
	// We were executing an output ...
	if (output_fired) {
	  // ... and the output output did something.
	  output_buffer_a_ = action_.automaton->lookup_buffer (bda);
	  // Synchronize the buffers.
	  if (output_buffer_a_.get () != 0) {
	    output_buffer_a_->sync (0, output_buffer_a_->size ());
	  }
	  output_buffer_b_ = action_.automaton->lookup_buffer (bdb);
	  if (output_buffer_b_.get () != 0) {
	    output_buffer_b_->sync (0, output_buffer_b_->size ());
	  }
	  // Proceed to execute the inputs.
	  input_action_pos_ = input_action_list_.begin ();
	  // This does not return if there are inputs.
	  proceed_to_input ();
	}
	// No input actions to execute.
	// -EEE
	action_.automaton->unlock_execution ();
	finish_output ();
	break;
      case INTERNAL:
      case SYSTEM:
	// -EEE
	action_.automaton->unlock_execution ();
	break;
      }
    }

    // We are done with the current action.
    action_.automaton = shared_ptr<automaton> ();

    for (;;) {

      irq_handler::process_interrupts ();

      while (!ready_queue_.empty ()) {
	// Get the automaton context and remove it from the ready queue.
	automaton_context* c = ready_queue_.front ();
	ready_queue_.pop_front ();

	// Load the action.
	action_ = c->front ();
	c->pop_front ();

	// The automaton exists.  Continue loading and execute.
	switch (action_.action->type) {
	case INPUT:
	  // Error.  Not a local action.
	  kpanic ("Non-local action on execution queue");
	  break;
	case OUTPUT:
	  {
	    kassert (input_action_list_.empty ());
	    // Copy the bindings.
	    action_.automaton->copy_bound_inputs (action_, back_inserter (input_action_list_));
	    
	    // Sort the bindings by input automaton.
	    sort (input_action_list_.begin (), input_action_list_.end (), sort_bindings_by_input ());
	    
	    // We lock the automata in order.  This is called Havender's Principle.
	    bool output_locked = false;
	    for (input_action_list_type::const_iterator pos = input_action_list_.begin ();
		 pos != input_action_list_.end ();
		 ++pos) {
	      shared_ptr<automaton> input_automaton = (*pos)->input_action.automaton;
	      if (!output_locked && action_.automaton->aid () < input_automaton->aid ()) {
		// +EEE
		action_.automaton->lock_execution ();
		output_locked = true;
	      }
	      // +FFF
	      input_automaton->lock_execution ();
	    }
	    if (!output_locked) {
	      // +EEE
	      action_.automaton->lock_execution ();
	      output_locked = true;
	    }
	    
	    input_action_pos_ = input_action_list_.begin ();
	  }
	  break;
	case INTERNAL:
	case SYSTEM:
	  // +EEE
	  action_.automaton->lock_execution ();
	  break;
	}
	
	if (!c->empty ()) {
	  // Automaton has more actions, return to ready queue.
	  ready_queue_.push_back (c);
	}

	action_.automaton->execute (*action_.action, action_.parameter, output_buffer_a_, output_buffer_b_);
      }

      // Out of actions.
      action_.automaton = shared_ptr<automaton> ();
      irq_handler::wait_for_interrupt ();
    }
  }
示例#2
0
int dna_ode_run (int argc, char **argv, config_t *simconfig) {
  int retcode;
  simparameters *simparams;
  simcontext *simcon;

  /*
   * INITIALIZATION
   */

  /* check that seed was given */
  if (argc < 4) {
    print_usage_run (argv [0]);
    exit (EXIT_FAILURE);
  }

  /* memory allocation for the simulation parameters, statistics, and context */
  simparams = (simparameters *) malloc (sizeof (simparameters));
  simcon = (simcontext *) malloc (sizeof (simcontext));

  /* get RNG seed */
  simparams->seed = atoi (argv [3]);

  /* initialization of ODE */
  dInitODE ();

  /*
   * INITIALIZE SIMULATION PARAMETERS, RANDOM NUMBER GENERATION, AND CONTEXT
   */
  init_simulation_parameters (simparams, simconfig);
  my_init_RNG (simparams->seed);
  init_simulation_context (simcon, simparams);

  /*
   * NOW WE SWITCH TO THE SYSTEM CHOSEN
   */
  switch (simparams->sysid) {
    case SDNA :
      retcode = sdna_main (simcon);
      break;
    case FDNA :
      retcode = fdna_main (simcon);
      break;
    case CDNA :
      retcode = cdna_main (simcon);
      break;
    default :
      err_message ("Invalid system ID\n");
      return 1;
  }

  /* final stuff to terminal */
  finish_output (simcon);

  /* close output files */
  close_output_files (simcon);

  /* free memory */
  free_memory (simcon);

  /* close ODE */
  dCloseODE();

  return retcode;
}