This is the mail archive of the sid@sources.redhat.com mailing list for the SID project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

[patch][RFA]: Sid scheduling for debugging multiple cpus


Hi,

A while back I checked in a patch which allows multiple GDB debuggers to 
be connected to multiple processors in a sid simulation (see --gdbport 
option). This patch completes the work by modifying the scheduler 
component to allow the system to remain coherent which under the control 
of these multiple debuggers.

The basic idea is that the target-scheduler's 'enabled?' attribute is no 
longer a toggle (on or off) but rather is now a value which is 
incremented or decremented. Similarly for the 'yield-host-time?' 
attribute. In addition there are new attributes: 'enable-threshold' and 
'yield-host-time-threshold'. With the old boolean attributes, the 
scheduler was enabled when the 'enabled?' attribute was non zero and the 
scheduler could yield when 'yield-host-time' was non zero. Now these 
activities occur when the value of the attribute is equal to, or greater 
than the corresponding threshold.

This is required for a multiple GDB simulation since we want the 
simulation to proceed iff all of the gdb components believe that the 
target is running. If one or more GDBs believe that the target is 
stopped, then it will be. The others will simply believe that the target 
is taking a long time to run. Similarly, the scheduler may yield if one 
or more of the GDBs believe that the target is stopped.

This is accomplished in the configuration by setting the 
'enable-threshold' to the number of GDBs controlling the simulation. The 
'enable?' attribute is incremented by each GDB as the user instructs 
each to run the target in some way (i.e. continue, step, etc). 
Similarly, 'yield-host-time-threshold' is set to 1 and 'yield-host-time' 
initialized to the number of GDBs. This attribute is decremented as each 
GDB tries to run the target. Thus the host scheduler may yield when the 
target is stopped and may yield when the target is actually running.

The default values are enable-threshold==1 and 
yield-host-time-threshold==1 which allow single-GDB and non-GDB 
simulations to run as expected.

This patch has been tested on m32r as well as 2 internal ports.

Dave
2001-10-16  Dave Brolley  <brolley@redhat.com>

	* configrun-sid.in: Move check of $opt_persistent and $opt_verbose to
	just before output.
	Check for gdb components attached to processors other than the main
	cpu. Adjust the enable-threshold of target-sched accordingly.

2001-10-16  Dave Brolley  <brolley@redhat.com>

	* compSched.cxx (operator <<): Save state of enable_threshold and
	yield_host_time_threshold.
	(operator >>): Restore state of enable_threshold and
	yield_host_time_threshold.
	(class scheduler_component): New members: enable_threshold,
	yield_host_time_threshold.
	(scheduler_component::advance): Check enable_p against enable_threshold.
	Check yield_host_time_p against yield_host_time_theshold.
	(scheduler_component): Initialize enable_threshold, enable_p,
	yield_host_time_p and yield_host_time_threshold.
	(scheduler_component_ctor_1): Add attributes 'enable-threshold' and
	'yield-host-time-threshold'.

2001-10-16  Dave Brolley  <brolley@redhat.com>

	* integrated.s: Add labels for gdb testing.
	* integrated-copro.s: Ditto.

Index: sid/bsp/configrun-sid.in
===================================================================
RCS file: /cvs/src/src/sid/bsp/configrun-sid.in,v
retrieving revision 1.23
diff -c -p -r1.23 configrun-sid.in
*** sid/bsp/configrun-sid.in	2001/10/04 17:33:48	1.23
--- sid/bsp/configrun-sid.in	2001/10/16 21:35:48
*************** $zeroth_section = "# sid configuration f
*** 345,354 ****
  # run by $whoami @ $hostname ($uname) at $date
  # args: @ARGV_COPY\n";
  
- if ($opt_verbose) { $zeroth_section .= "set main verbose? true\n"; }
- if ($opt_persistent) { $zeroth_section .= "set main persistent? true\n"; }
- 
- 
  $cpu_component_type = $cpu_comptype{$opt_cpu} || die "Unknown cpu $opt_cpu for cpu component type\n";
  $first_section = "# first section\n" .
    &sidconf_new("$cpu_component_type", "cpu") . "\n" .
--- 345,350 ----
*************** else
*** 854,859 ****
--- 850,856 ----
  
  # --gdb
  # Generate a gdb component for each processor requested.
+ $non_cpu_gdbs=0;
  foreach $processor (keys %opt_gdbport)
    {
      $first_section .= "# $processor gdb\n" .
*************** connect-pin host-sched 6-event -> ${proc
*** 882,889 ****
--- 879,905 ----
  connect-pin host-sched 6-control <- ${processor}-gdb-socket poll-control
  set ${processor}-gdb-socket sockaddr-local 0.0.0.0:$opt_gdbport{$processor}\n" .
  ($opt_verbose ? "set ${processor}-gdb-socket verbose? $opt_verbose\n" : "");
+     if ($processor ne "cpu")
+       {
+ 	$non_cpu_gdbs ++;
+       }
    }
  
+ # Update the enable thresholds of the shedulers to account for GDB components
+ # attached to processors other than the cpu.
+ if ($non_cpu_gdbs != 0)
+   {
+     $opt_persistent = 1;
+     $sched_threshold = $non_cpu_gdbs + 1;
+     $third_section .= "
+ # We want the target scheduler to come up enabled, so update the enabled?
+ # attribute to match the threshold. The GDB components will take care of
+ # disabling it when necessary.
+ set target-sched enable-threshold $sched_threshold
+ set target-sched enabled? $sched_threshold
+ ";
+   }
+ 
  # Additional settings for main cpu gdb.
  if ($opt_gdb)
    {
*************** foreach $lib (sort keys %component_libs)
*** 1149,1155 ****
  
  
  # ----------------------------------------------------------------------------
! 
  
  # Build config file
  $tmpdir = $ENV{'TMPDIR'} ? $ENV{'TMPDIR'} : "/tmp";
--- 1165,1172 ----
  
  
  # ----------------------------------------------------------------------------
! if ($opt_verbose) { $zeroth_section .= "set main verbose? true\n"; }
! if ($opt_persistent) { $zeroth_section .= "set main persistent? true\n"; }
  
  # Build config file
  $tmpdir = $ENV{'TMPDIR'} ? $ENV{'TMPDIR'} : "/tmp";
Index: sid/component/gdb/gdb.cxx
===================================================================
RCS file: /cvs/src/src/sid/component/gdb/gdb.cxx,v
retrieving revision 1.7
diff -c -p -r1.7 gdb.cxx
*** sid/component/gdb/gdb.cxx	2001/10/03 17:06:01	1.7
--- sid/component/gdb/gdb.cxx	2001/10/16 21:35:48
*************** gdb::process_detach ()
*** 1040,1045 ****
--- 1040,1072 ----
      }
  }
  
+ // Increment a given attribute value, interpreted as a plain `int'.
+ static void 
+ increment_attribute (sid::component* comp, const string& attr, int increment)
+ {
+   assert(comp);
+   string valstr = comp->attribute_value (attr);
+   int num;
+   component::status s = parse_attribute(valstr, num);
+   if (s != component::ok)
+     {
+       cerr << "Cannot parse " << attr << " attribute: string " << valstr
+ 	   << " status " << (int) s << endl;
+       return;
+     }
+   
+   num += increment;
+   
+   valstr = make_numeric_attribute (num);
+   
+   s = comp->set_attribute_value (attr, valstr);
+   if (s != component::ok)
+     {
+       cerr << "Cannot set " << attr << " attribute: string " << valstr
+ 	   << " status " << (int) s << endl;
+       return;
+     }
+ }
  
  void
  gdb::target_power (bool on)
*************** gdb::target_power (bool on)
*** 1053,1078 ****
    // signal target system to yield
    this->yield_pin.drive (0);
  
!   // Set/clear enabled? attribute of target schedulers
    for (unsigned i=0; i<target_schedulers.size(); i++)
      {
!       assert(target_schedulers[i]);
!       component::status s = target_schedulers[i]->set_attribute_value ("enabled?", (on ? "1" : "0"));
!       if (s != component::ok)
  	{
! 	  cerr << "Cannot set enabled? attribute in scheduler: status " << (int) s << endl;
  	}
      }
  
!   // Set/clear yield-host-time? attribute of host schedulers
    for (unsigned j=0; j<host_schedulers.size(); j++)
      {
!       assert(host_schedulers[j]);
!       component::status s = host_schedulers[j]->set_attribute_value ("yield-host-time?",
! 							      (on ? "0" : "1"));
!       if (s != component::ok)
  	{
! 	  cerr << "Cannot set yield? attribute in scheduler: status " << (int) s << endl;
  	}
      }
  }
--- 1080,1113 ----
    // signal target system to yield
    this->yield_pin.drive (0);
  
!   // increment/decrement enabled? attribute of target schedulers when 'on'
!   // is true/false respectively.  Do not increment/decrement the attribute
!   // if the scheduler is already enabled/disabled from our point of view.
!   int incr = on ? 1 : -1;
    for (unsigned i=0; i<target_schedulers.size(); i++)
      {
!       bool enabled = target_schedulers_enabled[i];
!       if (trace_gdbsid)
! 	cerr << "  Target scheduler " << i << " enabled==" << enabled << endl;
!       if (enabled != on)
  	{
! 	  increment_attribute (target_schedulers[i], "enabled?", incr);
! 	  target_schedulers_enabled[i] = on;
  	}
      }
  
!   // increment/decrement enabled? attribute of host schedulers when 'on'
!   // is false/true respectively.  Do not increment/decrement the attribute
!   // if the scheduler is already enabled/disabled from our point of view.
    for (unsigned j=0; j<host_schedulers.size(); j++)
      {
!       bool yielded = host_schedulers_host_time_yielded[j];
!       if (trace_gdbsid)
! 	cerr << "  Host scheduler " << j << " yielded==" << yielded << endl;
!       if (yielded == on)
  	{
! 	  increment_attribute (host_schedulers[j], "yield-host-time?", -incr);
! 	  host_schedulers_host_time_yielded[j] = ! on;
  	}
      }
  }
*************** gdb::init_handler (host_int_4) 
*** 1251,1257 ****
        cerr << "sid-gdb: no debug cpu specified." << endl;
        return;
      }
!   
    // suspend down target system
    target_power (false);
  }
--- 1286,1298 ----
        cerr << "sid-gdb: no debug cpu specified." << endl;
        return;
      }
! 
!   // Initialize vectors representing the state of each host/target scheduler.
!   for (unsigned i=0; i<target_schedulers.size(); i++)
!     target_schedulers_enabled.push_back (true);
!   for (unsigned j=0; j<host_schedulers.size(); j++)
!     host_schedulers_host_time_yielded.push_back (false);
! 
    // suspend down target system
    target_power (false);
  }
Index: sid/component/gdb/gdb.h
===================================================================
RCS file: /cvs/src/src/sid/component/gdb/gdb.h,v
retrieving revision 1.5
diff -c -p -r1.5 gdb.h
*** sid/component/gdb/gdb.h	2001/10/03 17:06:01	1.5
--- sid/component/gdb/gdb.h	2001/10/16 21:35:48
*************** private:
*** 114,119 ****
--- 114,121 ----
    output_pin yield_pin; // signal to target subsystem
    vector<component*> target_schedulers;
    vector<component*> host_schedulers;
+   vector<bool> target_schedulers_enabled;
+   vector<bool> host_schedulers_host_time_yielded;
    // turn target subsystem on/off
    output_pin process_signal_pin;  // signal to cfgroot
    output_pin restart_pin; // signal to hw-reset
Index: sid/component/sched/compSched.cxx
===================================================================
RCS file: /cvs/src/src/sid/component/sched/compSched.cxx,v
retrieving revision 1.5
diff -c -p -r1.5 compSched.cxx
*** sid/component/sched/compSched.cxx	2001/09/13 21:05:07	1.5
--- sid/component/sched/compSched.cxx	2001/10/16 21:35:48
*************** ostream& 
*** 1139,1145 ****
--- 1139,1147 ----
  operator << (ostream& o, const scheduler_component<Scheduler>& it)
  {
    o << "scheduler-state "
+     << it.enable_threshold << " "
      << it.enable_p << " "
+     << it.yield_host_time_threshold << " "
      << it.yield_host_time_p << " "
      << it.sched.step_cycle_limit << " "   // this is a component attribute
      << it.advance_count << " "
*************** operator >> (istream& i, scheduler_compo
*** 1182,1188 ****
    i >> key;
    if (key == "scheduler-state")
      {
!       i >> it.enable_p
  	>> it.yield_host_time_p
  	>> it.sched.step_cycle_limit
  	>> it.advance_count
--- 1184,1192 ----
    i >> key;
    if (key == "scheduler-state")
      {
!       i >> it.enable_threshold
!         >> it.enable_p
! 	>> it.yield_host_time_threshold
  	>> it.yield_host_time_p
  	>> it.sched.step_cycle_limit
  	>> it.advance_count
*************** class scheduler_component: public schedu
*** 1251,1258 ****
  
    vector<client_t*> clients;  
    host_int_1 num_clients;
!   bool enable_p;
!   bool yield_host_time_p;
    host_int_8 advance_count;
    callback_pin<this_t> advance_pin;
    callback_pin<this_t> time_query_pin;
--- 1255,1264 ----
  
    vector<client_t*> clients;  
    host_int_1 num_clients;
!   int enable_threshold;
!   int enable_p;
!   int yield_host_time_threshold;
!   int yield_host_time_p;
    host_int_8 advance_count;
    callback_pin<this_t> advance_pin;
    callback_pin<this_t> time_query_pin;
*************** protected:
*** 1298,1308 ****
        recursion_record limit (this);
        if (UNLIKELY(!limit.ok()))
  	return;
! 
!       if (LIKELY(this->enable_p))
          {
            this->advance_count ++;
!   	  this->sched.advance (this->yield_host_time_p);
          }
      }
  
--- 1304,1324 ----
        recursion_record limit (this);
        if (UNLIKELY(!limit.ok()))
  	return;
! #if 0
!       cerr << "Scheduler:" << endl;
!       cerr << "  enable_p==" << this->enable_p
! 	   << " enable_threshold==" << this->enable_threshold << endl;
! #endif
!       if (LIKELY(this->enable_p >= this->enable_threshold))
          {
+ #if 0
+ 	  cerr << "  yield_host_time_p=="
+ 	       << this->yield_host_time_p
+ 	       << " yield_host_time_threshold=="
+ 	       << this->yield_host_time_threshold << endl;
+ #endif
            this->advance_count ++;
!   	  this->sched.advance (this->yield_host_time_p >= this->yield_host_time_threshold);
          }
      }
  
*************** public:
*** 1395,1405 ****
      sched(),
      clients(0),
      num_clients(0),
!     enable_p(true), yield_host_time_p(false), 
      advance_pin(this, & scheduler_component::advance),
      time_query_pin(this, & scheduler_component::time_query),
      yield_pin(this, & scheduler_component::yield_step_loop)
      {
        scheduler_component_ctor_1();
        scheduler_component_ctor_2();
        scheduler_component_ctor_3();
--- 1411,1424 ----
      sched(),
      clients(0),
      num_clients(0),
!     enable_threshold(1),
!     yield_host_time_threshold(1), 
!     yield_host_time_p(0), 
      advance_pin(this, & scheduler_component::advance),
      time_query_pin(this, & scheduler_component::time_query),
      yield_pin(this, & scheduler_component::yield_step_loop)
      {
+       enable_p = enable_threshold;
        scheduler_component_ctor_1();
        scheduler_component_ctor_2();
        scheduler_component_ctor_3();
*************** scheduler_component<Scheduler>::schedule
*** 1419,1425 ****
--- 1438,1446 ----
    add_pin ("time-low", & this->time_low_pin);
    add_pin ("yield", & this->yield_pin);
    add_attribute ("yield", & this->yield_pin, "pin");
+   add_attribute ("enable-threshold", & this->enable_threshold, "setting");
    add_attribute ("enabled?", & this->enable_p, "setting");
+   add_attribute ("yield-host-time-threshold", & this->yield_host_time_threshold, "setting");
    add_attribute ("yield-host-time?", & this->yield_host_time_p, "setting");
    add_attribute_ro_value ("scheduler-control-gui", string("sid-visual-sched"), "gui");
  }

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]