This is the mail archive of the
sid@sources.redhat.com
mailing list for the SID project.
[patch][RFA]: Sid scheduling for debugging multiple cpus
- To: sid at sources dot redhat dot com
- Subject: [patch][RFA]: Sid scheduling for debugging multiple cpus
- From: Dave Brolley <brolley at redhat dot com>
- Date: Tue, 16 Oct 2001 18:17:45 -0400
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");
}