From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 16226 invoked by alias); 23 Aug 2005 21:24:50 -0000 Mailing-List: contact sid-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: sid-owner@sources.redhat.com Received: (qmail 15707 invoked by uid 22791); 23 Aug 2005 21:24:26 -0000 Received: from mx1.redhat.com (HELO mx1.redhat.com) (66.187.233.31) by sourceware.org (qpsmtpd/0.30-dev) with ESMTP; Tue, 23 Aug 2005 21:24:26 +0000 Received: from int-mx1.corp.redhat.com (int-mx1.corp.redhat.com [172.16.52.254]) by mx1.redhat.com (8.12.11/8.12.11) with ESMTP id j7NLOO5u027425 for ; Tue, 23 Aug 2005 17:24:24 -0400 Received: from pobox.toronto.redhat.com (pobox.toronto.redhat.com [172.16.14.4]) by int-mx1.corp.redhat.com (8.11.6/8.11.6) with ESMTP id j7NLOOV26366 for ; Tue, 23 Aug 2005 17:24:24 -0400 Received: from [172.16.14.227] (IDENT:XJURzcH8AeEIW/MCkB+R+14qFrLgMFn+@topaz.toronto.redhat.com [172.16.14.227]) by pobox.toronto.redhat.com (8.12.8/8.12.8) with ESMTP id j7NLOO1M020290 for ; Tue, 23 Aug 2005 17:24:24 -0400 Message-ID: <430B9407.6060806@redhat.com> Date: Tue, 23 Aug 2005 21:24:00 -0000 From: Dave Brolley User-Agent: Mozilla Thunderbird 1.0.2 (X11/20050317) MIME-Version: 1.0 To: sid@sources.redhat.com Subject: [patch][commit] Prioritization of Scheduler Events Content-Type: multipart/mixed; boundary="------------000501050206090609030603" X-SW-Source: 2005-q3/txt/msg00023.txt.bz2 This is a multi-part message in MIME format. --------------000501050206090609030603 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Content-length: 1760 Hi, While looking into some bugs with the recent dynamic configuration work, it became apparent that it would be necessary to have some control over when the dynamic configurator component's step! pin was drive in relation to the scheduling of other components. In particular, it is desirable that the dynamic configurator be stepped (if necessary) first, before other components scheduled at the same time are stepped. In this way, all components are stepped under the same configuration. After some experimentation with sequence components, it occurred to me that this could be easily accomplished if the events scheduled at a given time could be prioritized, so that they are dispatched in a predictable order. I've committed an implementation which adds a new attribute, N-priority, to each output of the generic_scheduler component which is analogous to the existing N-event and N-control pins and the N-time and N-regular attributes. N-priority is assigned an integral value with the default being zero. The higher the value, the higher the priority of that output. When multiple events are scheduled at the same time, they are dispatched in priority order. There is no change for existing ports since all outputs will be assigned a priority of zero. Also included in this patch is a change to assign the gprof component a priority of 1. In this way it will always take a sample before the cpu is driven. The dynamic configurator component is assigned a priority of 2, so that the entire system is configured (if necessary) before any other components are stepped. Note that there is no change to the number of events being dispatched. Simply a prioritization. Let me know if there are any problems or concerns. Dave Dave --------------000501050206090609030603 Content-Type: text/plain; name="sched-priority.ChangeLog" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="sched-priority.ChangeLog" Content-length: 2088 sid/component/cfgroot/ChangeLog: 2005-08-23 Dave Brolley * compConfig.cxx (reset): Drive step_control_pin. (get_current_config): Removed. * sid-control-dynamic-configurator.xml: Correct description of interface. * sid-control-dynamic-configurator.txt: Regenerated. sid/component/profiling/ChangeLog: 2005-08-23 Dave Brolley * gprof.cxx (configure): Don't reset the N-regular attribute of the scheduler. Call accumulate when configuring for cycles=N. sid/component/sched/ChangeLog: 2005-08-23 Dave Brolley * compSched.cxx (scheduling_event): Constructors now take a 'priority' argument. (operator <): Consider priority of events. (yield): Likewise. (next_event): Likewise. (schedule_irregular): Now takes a 'priority' argument. Used when creating scheduling events. (schedule_regular): Likewise. (refill_regular_events_table): Consider priority of events. (operator <<): Stream priority. (operator >>): Destream priority. (class scheduler_client): Add 'priority' member. (set_time): Pass priority of the client to the scheduler. (client_num_update): Handle N-priority attribute. * sid-sched.xml: Describe the N-priority attribute. * sid-sched.txt: Regenerated. sid/include/ChangeLog: 2005-08-23 Dave Brolley * sidcpuutil.h (step_pin_handler): Don't call configure_gprof here. (unconfigure_gprof): Check gprof_configured_p. (configure_gprof): Check gprof_configured_p. (configure_gprof_p): Removed. (gprof_spec): Removed. (configure): Call configure_gprof here. sid/main/dynamic/ChangeLog: 2005-08-23 Dave Brolley * mainDynamic.cxx (try_add_gprof): Initialize interval. * commonCfg.cxx (set_priority): New method of SchedCfg. (GprofCfg): Always call set_time, set_regular and set_priority. (BoardCfg::write_load): Don't connect init-seq to the dynamic configurator's step! pin. Call set_priority. * commonCfg.h (set_priority): New method of SchedCfg. (config_priority,gprof_priority,default_priority): New constants in SchedCfg. --------------000501050206090609030603 Content-Type: text/plain; name="sched-priority.patch.txt" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="sched-priority.patch.txt" Content-length: 36598 Index: sid/component/cfgroot/compConfig.cxx =================================================================== RCS file: /cvs/src/src/sid/component/cfgroot/compConfig.cxx,v retrieving revision 1.10 diff -c -p -r1.10 compConfig.cxx *** sid/component/cfgroot/compConfig.cxx 19 Aug 2005 19:39:07 -0000 1.10 --- sid/component/cfgroot/compConfig.cxx 23 Aug 2005 20:58:30 -0000 *************** dynamic_configurator_component::reset () *** 1389,1394 **** --- 1389,1396 ---- configure (spec); } } + + step_control_pin.drive (1); // reconfigure during next cycle } // Set the starting configuration Index: sid/component/profiling/gprof.cxx =================================================================== RCS file: /cvs/src/src/sid/component/profiling/gprof.cxx,v retrieving revision 1.12 diff -c -p -r1.12 gprof.cxx *** sid/component/profiling/gprof.cxx 19 Aug 2005 19:46:00 -0000 1.12 --- sid/component/profiling/gprof.cxx 23 Aug 2005 20:58:30 -0000 *************** namespace profiling_components *** 514,521 **** if (s == component::ok) { sim_sched->connect_pin (sim_sched_event + "-event", & accumulate_pin); - sim_sched->set_attribute_value (sim_sched_event + "-regular", "true"); sim_sched->set_attribute_value (sim_sched_event + "-time", make_attribute (cycles)); return; } } --- 514,523 ---- if (s == component::ok) { sim_sched->connect_pin (sim_sched_event + "-event", & accumulate_pin); sim_sched->set_attribute_value (sim_sched_event + "-time", make_attribute (cycles)); + // Take a sample now to make up for the one which just got cancelled when + // N-time was set. + accumulate (1); return; } } *************** namespace profiling_components *** 523,532 **** // No gprof config or cycles was not specified. We will not be triggered by the // target scheduler. if (sim_sched) ! { ! sim_sched->disconnect_pin (sim_sched_event + "-event", & accumulate_pin); ! sim_sched->set_attribute_value (sim_sched_event + "-regular", "false"); ! } return; } } --- 525,531 ---- // No gprof config or cycles was not specified. We will not be triggered by the // target scheduler. if (sim_sched) ! sim_sched->disconnect_pin (sim_sched_event + "-event", & accumulate_pin); return; } } Index: sid/component/sched/compSched.cxx =================================================================== RCS file: /cvs/src/src/sid/component/sched/compSched.cxx,v retrieving revision 1.12 diff -c -p -r1.12 compSched.cxx *** sid/component/sched/compSched.cxx 12 Feb 2005 16:25:47 -0000 1.12 --- sid/component/sched/compSched.cxx 23 Aug 2005 20:58:31 -0000 *************** *** 1,9 **** // compSched.cxx - the scheduler component. -*- C++ -*- ! // Copyright (C) 1999-2003 Red Hat. // This file is part of SID and is licensed under the GPL. // See the file COPYING.SID for conditions for redistribution. - #include "config.h" #include --- 1,8 ---- // compSched.cxx - the scheduler component. -*- C++ -*- ! // Copyright (C) 1999-2003, 2005 Red Hat. // This file is part of SID and is licensed under the GPL. // See the file COPYING.SID for conditions for redistribution. #include "config.h" #include *************** namespace scheduler_component *** 129,140 **** tick_t when; tick_t interval; output_pin* what; ! scheduling_event(): when(0), interval(0), what(0) {} ! scheduling_event(tick_t when, output_pin* what): ! when(when), interval(0), what(what) {} ! scheduling_event(tick_t when, tick_t interval, output_pin* what): ! when(when), interval(interval), what(what) {} }; // Define a comparison function for heaps of scheduling events. It --- 128,140 ---- tick_t when; tick_t interval; output_pin* what; + host_int_4 priority; ! scheduling_event(): when(0), interval(0), what(0), priority (0) {} ! scheduling_event(tick_t when, output_pin* what, host_int_4 priority): ! when(when), interval(0), what(what), priority(priority) {} ! scheduling_event(tick_t when, tick_t interval, output_pin* what, host_int_4 priority): ! when(when), interval(interval), what(what), priority(priority) {} }; // Define a comparison function for heaps of scheduling events. It *************** namespace scheduler_component *** 142,148 **** inline bool operator < (const scheduling_event& a, const scheduling_event& b) { ! return a.when > b.when; } --- 142,148 ---- inline bool operator < (const scheduling_event& a, const scheduling_event& b) { ! return (a.when > b.when) || ((a.when == b.when) && (a.priority < b.priority)); } *************** operator >> (istream& i, exact_host_time *** 603,609 **** } tick_t yield_until; ! if ( (rnext && irnext && (rnext->when < irnext->when)) || (rnext && !irnext)) yield_until = rnext->when; else if (irnext) --- 603,611 ---- } tick_t yield_until; ! if ((rnext && irnext ! && ((rnext->when < irnext->when) ! || (rnext->when == irnext->when && rnext->priority > irnext->priority))) || (rnext && !irnext)) yield_until = rnext->when; else if (irnext) *************** operator >> (istream& i, exact_host_time *** 674,680 **** rnext = & * this->regular_table_iter; } ! if ( (rnext && irnext && (rnext->when < irnext->when)) || (rnext && !irnext)) { return make_pair(rnext,true); --- 676,684 ---- rnext = & * this->regular_table_iter; } ! if ((rnext && irnext ! && ((rnext->when < irnext->when) ! || (rnext->when == irnext->when && rnext->priority > irnext->priority))) || (rnext && !irnext)) { return make_pair(rnext,true); *************** operator >> (istream& i, exact_host_time *** 789,795 **** // Schedule an irregular event. void ! schedule_irregular(tick_t delta, output_pin* what) { // cerr << "schedule_irregular when=" << when << endl; --- 793,799 ---- // Schedule an irregular event. void ! schedule_irregular(tick_t delta, output_pin* what, host_int_4 priority) { // cerr << "schedule_irregular when=" << when << endl; *************** operator >> (istream& i, exact_host_time *** 798,826 **** this->get_now(now); tick_t when = now + delta; ! this->irregular_events.push_back(scheduling_event(when, what)); push_heap(this->irregular_events.begin(), this->irregular_events.end()); } // Schedule a regular event, starting "when" void ! schedule_regular(tick_t when, tick_t interval, output_pin* what) { // cerr << "schedule_regular when=" << when << " interval=" << interval << endl; ! this->regular_events.push_back (scheduling_event(when, interval, what)); this->refill_regular_events_table(); } // Schedule a regular event starting "now" void ! schedule_regular(tick_t interval, output_pin* what) { // cerr << "scheduler_regular interval=" << interval << endl; // infer "now" as starting time tick_t now; this->get_now(now); ! this->schedule_regular (now, interval, what); } --- 802,830 ---- this->get_now(now); tick_t when = now + delta; ! this->irregular_events.push_back(scheduling_event(when, what, priority)); push_heap(this->irregular_events.begin(), this->irregular_events.end()); } // Schedule a regular event, starting "when" void ! schedule_regular(tick_t when, tick_t interval, output_pin* what, host_int_4 priority) { // cerr << "schedule_regular when=" << when << " interval=" << interval << endl; ! this->regular_events.push_back (scheduling_event(when, interval, what, priority)); this->refill_regular_events_table(); } // Schedule a regular event starting "now" void ! schedule_regular(tick_t interval, output_pin* what, host_int_4 priority) { // cerr << "scheduler_regular interval=" << interval << endl; // infer "now" as starting time tick_t now; this->get_now(now); ! this->schedule_regular (now, interval, what, priority); } *************** generic_scheduler::refill_re *** 935,946 **** { if (next_tick_time[reg] > next_tick_time[k]) reg = k; } slot->when = next_tick_time[reg]; slot->interval = 0; // initialize unused field slot->what = this->regular_events[reg].what; ! // cerr << " slot: when=" << slot->when << " what=" << slot->what << endl; next_tick_time[reg] += this->regular_events[reg].interval; } --- 939,954 ---- { if (next_tick_time[reg] > next_tick_time[k]) reg = k; + else if (next_tick_time[reg] == next_tick_time[k] + && this->regular_events[reg].priority < this->regular_events[k].priority) + reg = k; } slot->when = next_tick_time[reg]; slot->interval = 0; // initialize unused field slot->what = this->regular_events[reg].what; ! slot->priority = this->regular_events[reg].priority; ! // cerr << " slot: when=" << slot->when << " what=" << slot->what << " priority=" << slot->priority << endl; next_tick_time[reg] += this->regular_events[reg].interval; } *************** operator << (ostream& o, const generic_s *** 975,981 **** string name; bool ok = it.pin_state_map.find(e->what, name); assert (ok); ! o << " " << e->when << " " << e->interval << " " << name << endl; } o << it.regular_events.size() << endl; --- 983,989 ---- string name; bool ok = it.pin_state_map.find(e->what, name); assert (ok); ! o << " " << e->when << " " << e->priority << " " << e->interval << " " << name << endl; } o << it.regular_events.size() << endl; *************** operator << (ostream& o, const generic_s *** 988,994 **** string name; bool ok = it.pin_state_map.find(e->what, name); assert (ok); ! o << " " << e->when << " " << e->interval << " " << name << endl; } return o; --- 996,1002 ---- string name; bool ok = it.pin_state_map.find(e->what, name); assert (ok); ! o << " " << e->when << " " << e->priority << " " << e->interval << " " << name << endl; } return o; *************** operator >> (istream& i, generic_schedul *** 1024,1031 **** for(unsigned t=0; t> when >> interval >> name; // make base time absolute when += delta; // find new pin --- 1032,1040 ---- for(unsigned t=0; t> when >> priority >> interval >> name; // make base time absolute when += delta; // find new pin *************** operator >> (istream& i, generic_schedul *** 1033,1039 **** bool ok = it.pin_state_map.find(name, pin); assert (ok); // add it ! it.irregular_events.push_back(scheduling_event(when, interval, pin)); } // Clear regular events table --- 1042,1048 ---- bool ok = it.pin_state_map.find(name, pin); assert (ok); // add it ! it.irregular_events.push_back(scheduling_event(when, interval, pin, priority)); } // Clear regular events table *************** operator >> (istream& i, generic_schedul *** 1045,1052 **** for(unsigned t=0; t> when >> interval >> name; // make base time absolute when += delta; // find new pin --- 1054,1062 ---- for(unsigned t=0; t> when >> priority >> interval >> name; // make base time absolute when += delta; // find new pin *************** operator >> (istream& i, generic_schedul *** 1054,1060 **** bool ok = it.pin_state_map.find(name, pin); assert (ok); // add it ! it.regular_events.push_back(scheduling_event(when, interval, pin)); } // get scheduler ready for operation with new data --- 1064,1070 ---- bool ok = it.pin_state_map.find(name, pin); assert (ok); // add it ! it.regular_events.push_back(scheduling_event(when, interval, pin, priority)); } // get scheduler ready for operation with new data *************** public: *** 1083,1088 **** --- 1093,1099 ---- host_int_2 scale_mul, scale_div; // time-to-ticks conversion factor tick_t time; // time of next event (irregular) or interval (regular) bool regular_p; // regular (vs irregular) event source + host_int_4 priority; // priority of client string name; // "pretty" name, for use in scheduler GUI // These are public members for direct pin map twiddlers *************** private: *** 1103,1120 **** // silently prevent division-by-zero if (this->scale_div == 0) this->scale_div = 1; - tick_t sched_time = t * this->scale_mul / this->scale_div; if (LIKELY(t != 0)) { // round up away from zero if (sched_time == 0) sched_time = 1; if (this->regular_p) ! this->comp->sched.schedule_regular (sched_time, & this->event_pin); else ! this->comp->sched.schedule_irregular (sched_time, & this->event_pin); } } --- 1114,1131 ---- // silently prevent division-by-zero if (this->scale_div == 0) this->scale_div = 1; if (LIKELY(t != 0)) { // round up away from zero + tick_t sched_time = t * this->scale_mul / this->scale_div; if (sched_time == 0) sched_time = 1; if (this->regular_p) ! this->comp->sched.schedule_regular (sched_time, & this->event_pin, this->priority); else ! this->comp->sched.schedule_irregular (sched_time, & this->event_pin, this->priority); } } *************** public: *** 1140,1145 **** --- 1151,1157 ---- scale_div (1), time (0), regular_p (true), + priority (0), event_pin (), control_pin(this, & scheduler_client::set_control), comp(comp) *************** operator << (ostream& o, const scheduler *** 1236,1242 **** << it.clients[j]->time << " " << it.clients[j]->scale_mul << " " << it.clients[j]->scale_div << " " ! << it.clients[j]->regular_p << endl; its.add_pin_mapping((make_numeric_attribute(j) + "-event"), & it.clients[j]->event_pin); } --- 1248,1256 ---- << it.clients[j]->time << " " << it.clients[j]->scale_mul << " " << it.clients[j]->scale_div << " " ! << it.clients[j]->regular_p << " " ! << it.clients[j]->priority << " " ! << endl; its.add_pin_mapping((make_numeric_attribute(j) + "-event"), & it.clients[j]->event_pin); } *************** operator >> (istream& i, scheduler_compo *** 1282,1288 **** i >> it.clients[j]->time >> it.clients[j]->scale_mul >> it.clients[j]->scale_div ! >> it.clients[j]->regular_p; it.sched.add_pin_mapping((make_numeric_attribute(j) + "-event"), & it.clients[j]->event_pin); --- 1296,1303 ---- i >> it.clients[j]->time >> it.clients[j]->scale_mul >> it.clients[j]->scale_div ! >> it.clients[j]->regular_p ! >> it.clients[j]->priority; it.sched.add_pin_mapping((make_numeric_attribute(j) + "-event"), & it.clients[j]->event_pin); *************** scheduler_component::client_n *** 1522,1527 **** --- 1537,1543 ---- string num = sidutil::make_numeric_attribute(n); this->remove_attribute (num + "-regular?"); this->remove_attribute (num + "-time"); + this->remove_attribute (num + "-priority"); this->remove_attribute (num + "-scale"); this->remove_attribute (num + "-name"); this->remove_attribute (num + "-event"); *************** scheduler_component::client_n *** 1549,1554 **** --- 1565,1574 ---- & c->time, c, & client_t::reset_events, "setting"); + this->add_attribute_notify (num + "-priority", + & c->priority, c, + & client_t::reset_events, + "setting"); this->add_attribute_virtual (num + "-scale", c, & client_t::get_scale_attr, & client_t::set_scale_attr, "setting"); Index: sid/component/sched/sid-sched.txt =================================================================== RCS file: /cvs/src/src/sid/component/sched/sid-sched.txt,v retrieving revision 1.7 diff -c -p -r1.7 sid-sched.txt *** sid/component/sched/sid-sched.txt 21 Oct 2003 21:36:29 -0000 1.7 --- sid/component/sched/sid-sched.txt 23 Aug 2005 20:58:31 -0000 *************** Functionality: *** 95,118 **** | | | | | Each subscription is defined by | | | an index, a | ! | | regular-vs-irregular flag, and | ! | | a time quantity. The index is a | ! | | number between 0 and | ! | | num-clients -1, and is | | | represented as N in the | | | pin/attribute list templates in | | | this document. The | | | regular-vs-irregular flag is | | | accessible as the N-regular? | ! | | attribute. The time quantity is | ! | | accessible as the N-time | ! | | attribute. If the value is | ! | | zero, it is interpreted as a | ! | | request to cancel all pending | ! | | events for this subscription. | ! | | Otherwise, the value is taken | ! | | to be a delta until the time of | ! | | the requested event. | | | | | | You can also set these controls | | | by driving encoded values into | --- 95,122 ---- | | | | | Each subscription is defined by | | | an index, a | ! | | regular-vs-irregular flag, a | ! | | priority and a time quantity. | ! | | The index is a number between 0 | ! | | and num-clients -1, and is | | | represented as N in the | | | pin/attribute list templates in | | | this document. The | | | regular-vs-irregular flag is | | | accessible as the N-regular? | ! | | attribute. The priority is | ! | | accessible as the N-priority | ! | | attribute. Higher values | ! | | indicate higher priority. The | ! | | time quantity is accessible as | ! | | the N-time attribute. If the | ! | | value is zero, it is | ! | | interpreted as a request to | ! | | cancel all pending events for | ! | | this subscription. Otherwise, | ! | | the value is taken to be a | ! | | delta until the time of the | ! | | requested event. | | | | | | You can also set these controls | | | by driving encoded values into | *************** Functionality: *** 181,186 **** --- 185,198 ---- | | This loop may be aborted early | | | if the yield input pin is | | | driven. | + | | | + | | If more than one event is | + | | scheduled at the same time. | + | | Events will be dispatched in | + | | priority order. Events with | + | | higher priority will be | + | | dispatched before events with | + | | lower priority. | +-------------------------------------------------+ +-------------------------------------------------+ *************** Component Reference: *** 291,296 **** --- 303,310 ---- |---------------------------+----------+----------+-----------+---------------|| |N-time |setting |numeric |'0' |subscription || |---------------------------+----------+----------+-----------+---------------|| + |N-priority |setting |numeric |'0' |subscription || + |---------------------------+----------+----------+-----------+---------------|| |N-scale |setting |numeric |'1' |subscription || | | |fraction | | || |---------------------------+----------+----------+-----------+---------------|| Index: sid/component/sched/sid-sched.xml =================================================================== RCS file: /cvs/src/src/sid/component/sched/sid-sched.xml,v retrieving revision 1.6 diff -c -p -r1.6 sid-sched.xml *** sid/component/sched/sid-sched.xml 21 Oct 2003 21:36:29 -0000 1.6 --- sid/component/sched/sid-sched.xml 23 Aug 2005 20:58:31 -0000 *************** *** 22,27 **** --- 22,28 ---- + *************** *** 110,120 ****

Each subscription is defined by an index, a ! regular-vs-irregular flag, and a time quantity. The index is a number between 0 and num-clients -1, and is represented as N in the pin/attribute list templates in this document. The regular-vs-irregular flag is accessible as the N-regular? ! attribute. The time quantity is accessible as the N-time attribute. If the value is zero, it is interpreted as a request to cancel all pending events for this subscription. Otherwise, the value is taken to be a delta until the time of the --- 111,123 ----

Each subscription is defined by an index, a ! regular-vs-irregular flag, a priority and a time quantity. The index is a number between 0 and num-clients -1, and is represented as N in the pin/attribute list templates in this document. The regular-vs-irregular flag is accessible as the N-regular? ! attribute. The priority is accessible as the N-priority ! attribute. Higher values indicate higher priority. ! The time quantity is accessible as the N-time attribute. If the value is zero, it is interpreted as a request to cancel all pending events for this subscription. Otherwise, the value is taken to be a delta until the time of the *************** *** 166,171 **** --- 169,179 ---- the yield input pin is driven.

+

If more than one event is scheduled at the same time. Events will be dispatched in + priority order. Events with higher priority will be dispatched before events with lower + priority. +

+ Index: sid/include/sidcpuutil.h =================================================================== RCS file: /cvs/src/src/sid/include/sidcpuutil.h,v retrieving revision 1.31 diff -c -p -r1.31 sidcpuutil.h *** sid/include/sidcpuutil.h 19 Aug 2005 19:47:44 -0000 1.31 --- sid/include/sidcpuutil.h 23 Aug 2005 20:58:31 -0000 *************** namespace sidutil *** 270,278 **** recursion_record limit (& this->step_limit); if (UNLIKELY(! limit.ok())) return; - if (UNLIKELY (! gprof_configured_p && configure_gprof_p)) - configure_gprof (); - this->current_step_insn_count = 0; this->yield_p = false; --- 270,275 ---- *************** namespace sidutil *** 450,503 **** return static_cast(trap_disposition_pin.sense ()); } ! void unconfigure_gprof (sid::host_int_4 num_cycles) { assert (gprof); - // First sample the address of the branch which caused - // the reconfig for the given number of cycles. sid::pin *p; ! if (num_cycles && last_caller) { ! p = gprof->find_pin ("sample"); ! if (p) { ! std::string save_pc = this->attribute_value ("pc"); ! if (! save_pc.empty ()) { ! sid::component::status s = this->set_attribute_value ("pc", make_numeric_attribute (last_caller)); ! if (s == sid::component::ok) ! do ! { ! p->driven (1); ! --num_cycles; ! } while (num_cycles); ! this->set_attribute_value ("pc", save_pc); } } } ! ! // Then get gprof to reconfigure itself. ! gprof->set_attribute_value ("configure!", gprof_spec); // Then disconnect the call graph notification pins. - assert (! configure_gprof_p); - assert (gprof_configured_p); p = gprof->find_pin ("cg-caller"); if (p) cg_caller_pin.disconnect (p); p = gprof->find_pin ("cg-callee"); ! if (p) cg_callee_pin.disconnect (p); gprof_configured_p = false; } void configure_gprof () { ! // First get gprof to reconfigure itself. ! assert (gprof); ! gprof->set_attribute_value ("configure!", gprof_spec); ! // Then connect the call graph notification pins. ! assert (configure_gprof_p); ! assert (! gprof_configured_p); sid::pin *p = gprof->find_pin ("cg-caller"); if (p) { --- 447,502 ---- return static_cast(trap_disposition_pin.sense ()); } ! void unconfigure_gprof (const string &gprof_spec, sid::host_int_4 num_cycles) { + if (! gprof_configured_p) + return; + assert (gprof); sid::pin *p; ! ! #if 0 // can't happen? ! // If 'cycles' was specified on the --gprof option, then ! // first, sample the address of the branch which caused ! // the reconfig for the given number of cycles. ! if (num_cycles && last_caller && gprof_spec.size () > 6) { ! vector parts = tokenize (gprof_spec.substr (6), ","); ! if (parts.size () > 1) { ! p = gprof->find_pin ("sample"); ! if (p) { ! std::string save_pc = this->attribute_value ("pc"); ! if (! save_pc.empty ()) ! { ! sid::component::status s = this->set_attribute_value ("pc", make_numeric_attribute (last_caller)); ! if (s == sid::component::ok) ! for (int i = 0; i < num_cycles; ++i) ! p->driven (1); ! this->set_attribute_value ("pc", save_pc); ! } } } } ! #endif // Then disconnect the call graph notification pins. p = gprof->find_pin ("cg-caller"); if (p) cg_caller_pin.disconnect (p); p = gprof->find_pin ("cg-callee"); ! if (p) cg_callee_pin.disconnect (p); ! gprof_configured_p = false; } void configure_gprof () { ! if (gprof_configured_p) ! return; ! // Connect the call graph notification pins. ! assert (gprof); sid::pin *p = gprof->find_pin ("cg-caller"); if (p) { *************** namespace sidutil *** 511,516 **** --- 510,516 ---- if (last_caller && last_callee) p->driven (last_callee); } + gprof_configured_p = true; } *************** namespace sidutil *** 520,530 **** component *gprof; component *core_probe; component *main; - bool gprof_configured_p; - bool configure_gprof_p; sid::host_int_4 last_caller; sid::host_int_4 last_callee; ! string gprof_spec; virtual void configure (const string &config) { --- 520,528 ---- component *gprof; component *core_probe; component *main; sid::host_int_4 last_caller; sid::host_int_4 last_callee; ! bool gprof_configured_p; virtual void configure (const string &config) { *************** namespace sidutil *** 538,551 **** { if (! gprof) return; // nothing to configure ! gprof_spec = config; ! // Set a flag to configure the gprof component the next time ! // our step! pin is driven.... ! configure_gprof_p = (config.size () > 6); ! // ... unless we are unconfiguring the gprof, in which ! // case do it now. ! if (gprof_configured_p && ! configure_gprof_p) ! unconfigure_gprof (num_cycles); return; } if (config.size () <= 11) --- 536,548 ---- { if (! gprof) return; // nothing to configure ! // First get gprof to configure itself ! gprof->set_attribute_value ("configure!", config); ! // Now do our own configuration ! if (config.size () > 6) ! configure_gprof (); ! else ! unconfigure_gprof (config, num_cycles); return; } if (config.size () <= 11) *************** public: *** 754,763 **** trace_filename ("-"), // standard output trace_pin (this, & basic_cpu::trace_pin_handler), gprof (0), - gprof_configured_p (false), - configure_gprof_p (false), last_caller (0), last_callee (0), core_probe (0), main (0) { --- 751,759 ---- trace_filename ("-"), // standard output trace_pin (this, & basic_cpu::trace_pin_handler), gprof (0), last_caller (0), last_callee (0), + gprof_configured_p (false), core_probe (0), main (0) { Index: sid/main/dynamic/commonCfg.cxx =================================================================== RCS file: /cvs/src/src/sid/main/dynamic/commonCfg.cxx,v retrieving revision 1.10 diff -c -p -r1.10 commonCfg.cxx *** sid/main/dynamic/commonCfg.cxx 19 Aug 2005 19:48:45 -0000 1.10 --- sid/main/dynamic/commonCfg.cxx 23 Aug 2005 20:58:31 -0000 *************** void SchedCfg::set_time (int n, int tv) *** 439,444 **** --- 439,451 ---- set (this, s + "-time", ts); } + void SchedCfg::set_priority (int n, int pv) + { + string s = sidutil::make_attribute (n); + string ps = sidutil::make_attribute (pv); + set (this, s + "-priority", ps); + } + void SchedCfg::write_config (Writer &w) { Setting (this, "num-clients", sidutil::make_attribute (n)).write_to (w); *************** GprofCfg::GprofCfg (const string name, *** 997,1014 **** // used now, it could be used due to dynamic configuration. assert (sess->sim_sched); int slot = sess->sim_sched->add_subscription (this, "sample"); ! if (type == simulated_cycles) ! { ! sess->sim_sched->set_regular (slot, true); ! sess->sim_sched->set_time (slot, interval); ! } ! else // default to instruction_count { string ev = sidutil::make_attribute (cpu->get_subscription_number()); ev += "-event"; conn_pin (sess->sim_sched, ev, this, "sample"); } sess->shutdown_seq->add_output (7, this, "store"); relate (this, "target-component", cpu); conn_pin (cpu, "cg-caller", this, "cg-caller"); --- 1004,1021 ---- // used now, it could be used due to dynamic configuration. assert (sess->sim_sched); int slot = sess->sim_sched->add_subscription (this, "sample"); + sess->sim_sched->set_regular (slot, true); + sess->sim_sched->set_time (slot, interval); + sess->sim_sched->set_priority (slot, SchedCfg::gprof_priority); ! if (type != simulated_cycles) { + // default to instruction_count string ev = sidutil::make_attribute (cpu->get_subscription_number()); ev += "-event"; conn_pin (sess->sim_sched, ev, this, "sample"); } + sess->shutdown_seq->add_output (7, this, "store"); relate (this, "target-component", cpu); conn_pin (cpu, "cg-caller", this, "cg-caller"); *************** GprofCfg::GprofCfg (const string name, *** 1034,1039 **** --- 1041,1049 ---- // used now, it could be used due to dynamic configuration. assert (sess->sim_sched); int slot = sess->sim_sched->add_subscription (this, "sample"); + sess->sim_sched->set_regular (slot, true); + sess->sim_sched->set_time (slot, 1); + sess->sim_sched->set_priority (slot, SchedCfg::gprof_priority); sess->shutdown_seq->add_output (7, this, "store"); relate (this, "target-component", cpu); *************** void BoardCfg::write_load (Writer &w) *** 1228,1236 **** dynamic_configurator = new AtomicCfg ("dynamic-config", "libconfig.la", "config_component_library", "sid-control-dynamic-configurator"); - sess->init_seq->add_output (6, dynamic_configurator, "step!"); sess->reset_net->add_output (2, dynamic_configurator, "reset"); ! sess->sim_sched->add_subscription (dynamic_configurator, "step!", "step-control"); add_child (dynamic_configurator); // If we may need a gprof for dynamic configuration but don't have --- 1238,1246 ---- dynamic_configurator = new AtomicCfg ("dynamic-config", "libconfig.la", "config_component_library", "sid-control-dynamic-configurator"); sess->reset_net->add_output (2, dynamic_configurator, "reset"); ! int slot = sess->sim_sched->add_subscription (dynamic_configurator, "step!", "step-control"); ! sess->sim_sched->set_priority (slot, SchedCfg::config_priority); add_child (dynamic_configurator); // If we may need a gprof for dynamic configuration but don't have Index: sid/main/dynamic/commonCfg.h =================================================================== RCS file: /cvs/src/src/sid/main/dynamic/commonCfg.h,v retrieving revision 1.8 diff -c -p -r1.8 commonCfg.h *** sid/main/dynamic/commonCfg.h 19 Aug 2005 19:48:45 -0000 1.8 --- sid/main/dynamic/commonCfg.h 23 Aug 2005 20:58:38 -0000 *************** public: *** 109,115 **** --- 109,121 ---- string time_low); void set_regular (int n, bool v); void set_time (int n, int tv); + void set_priority (int n, int pv); virtual void write_config (Writer &w); + + static const int config_priority = 2; + static const int gprof_priority = 1; + static const int default_priority = 0; + protected: int n; }; Index: sid/main/dynamic/mainDynamic.cxx =================================================================== RCS file: /cvs/src/src/sid/main/dynamic/mainDynamic.cxx,v retrieving revision 1.7 diff -c -p -r1.7 mainDynamic.cxx *** sid/main/dynamic/mainDynamic.cxx 19 Aug 2005 19:48:45 -0000 1.7 --- sid/main/dynamic/mainDynamic.cxx 23 Aug 2005 20:58:38 -0000 *************** void try_add_gprof(const string optstrin *** 419,425 **** { gprof_type type; string interval_string; ! int interval; vector toks = sidutil::tokenize (optstring, ","); type = instruction_count; // default type value --- 419,425 ---- { gprof_type type; string interval_string; ! int interval = 1; vector toks = sidutil::tokenize (optstring, ","); type = instruction_count; // default type value --------------000501050206090609030603--