//=========================================================================== // Scheduler johns 10-2-00 // // The Scheduler schedules travel to occur on the route map. // It does this by forming a token consisting of the passenger ID and // destination ID from the itinerary leg passed into the 'ScheduleLeg' // port and sending it to the specified Origin transactor. The Origin // transactor will see to it that the token is sent to the nearest hub // in RouteMap at the specified time of departure. // // The secondary function of the scheduler is to load routes into the // route map tables at the request of the RouteConfig module. Such routes // arrive on the LoadRoute inslave port and are injected into the RouteMap // via the Waltham origin. For more information about programming the // RouteMap, see comments in RouteConfig. //=========================================================================== class Scheduler: public sc_module { public: //------------------------------------------------------- // Abstract port declarations sc_inmaster TodaysDate; sc_inslave ScheduleLeg; sc_inslave LoadRoute; sc_outmaster AnnounceArrival; private: SC_HAS_PROCESS(Scheduler); //------------------------------------------------------- // Context declarations SceMiMessageData dSendData; SceMiMessageInPortProxy *dOriginAnchorage; SceMiMessageInPortProxy *dOriginCupertino; SceMiMessageInPortProxy *dOriginNoida; SceMiMessageInPortProxy *dOriginSealBeach; SceMiMessageInPortProxy *dOriginUK; SceMiMessageInPortProxy *dOriginWaltham; SceMiMessageOutPortProxy *dDestinationAnchorage; SceMiMessageOutPortProxy *dDestinationCupertino; SceMiMessageOutPortProxy *dDestinationMaui; SceMiMessageOutPortProxy *dDestinationSealBeach; SceMiMessageOutPortProxy *dDestinationUK; Routed::ArrivalRecord dArrivalRecord; //------------------------------------------------------- // Thread declarations void scheduleLegThread(); void loadRouteThread(); //------------------------------------------------------- // Helper declarations static void replyCallback( void *context, const SceMiMessageData *data ); void announceArrival( SceMiU64 cycleStamp, SceMiU32 arrivalToken ); public: Scheduler( sc_module_name name, SceMi *sceMi ) : sc_module( name ), dSendData(Routed::MessageSize), dOriginAnchorage(NULL), dOriginCupertino(NULL), dOriginNoida(NULL), dOriginSealBeach(NULL), dOriginUK(NULL), dOriginWaltham(NULL), dDestinationAnchorage(NULL), dDestinationCupertino(NULL), dDestinationMaui(NULL), dDestinationSealBeach(NULL), dDestinationUK(NULL) { SC_SLAVE( scheduleLegThread, ScheduleLeg ); SC_SLAVE( loadRouteThread, LoadRoute ); // Establish message input portals. // SceMiMessageInPortBinding inBinding = { NULL, NULL, NULL }; dOriginAnchorage = sceMi->BindMessageInPort( "Bridge.anchorage.origin", "sceMiMessageInPort", NULL ); dOriginCupertino = sceMi->BindMessageInPort( "Bridge.cupertino.origin", "sceMiMessageInPort", NULL ); dOriginNoida = sceMi->BindMessageInPort( "Bridge.noida", "sceMiMessageInPort", NULL ); dOriginSealBeach = sceMi->BindMessageInPort( "Bridge.sealBeach.origin", "sceMiMessageInPort", NULL ); dOriginUK = sceMi->BindMessageInPort( "Bridge.UK.origin", "sceMiMessageInPort", NULL ); dOriginWaltham = sceMi->BindMessageInPort( "Bridge.waltham", "sceMiMessageInPort", NULL ); // Establish message output portals. SceMiMessageOutPortBinding outBinding = { this, replyCallback, NULL }; dDestinationAnchorage = sceMi->BindMessageOutPort( "Bridge.anchorage.destination", "sceMiMessageOutPort", &outBinding ); dDestinationCupertino = sceMi->BindMessageOutPort( "Bridge.cupertino.destination", "sceMiMessageOutPort", &outBinding ); dDestinationMaui = sceMi->BindMessageOutPort( "Bridge.maui", "sceMiMessageOutPort", &outBinding ); dDestinationSealBeach = sceMi->BindMessageOutPort( "Bridge.sealBeach.destination", "sceMiMessageOutPort", &outBinding ); dDestinationUK = sceMi->BindMessageOutPort( "Bridge.UK.destination", "sceMiMessageOutPort", &outBinding ); } }; //--------------------------------------------------------- // ::scheduleLegThread() - Shedule the given itinerary leg // // Description johnS 10-4-2000 // ----------- // This method forms a passenger token based on the given // itinerary leg record and sends it to the specified // origin. When the token is received by the origin // transactor, that transactor will delay sending it // to its destination by 'time of departure' number // of clocks. // // 'Passenger Departure' Token Format // // 31 27 15 7 3 0 // ____________________________________ // |time of departure| |dest| >0 | // +-----------------+------+--|-+--|-+ // | | // | +----> passenger ID // +---------> destination ID to which token is // enroute //--------------------------------------------------------- void Scheduler::scheduleLegThread(){ const Routed::Itinerary *leg = ScheduleLeg; // Form a 'Passenger Departure' token based on the contents of the given // 'Itinerary' record. SceMiU32 passengerDepartureToken = leg->PassengerID | (leg->DestinationID << 4) | (leg->OriginID << 12) | (leg->TimeOfDeparture << 16); dSendData.Set( 0, passengerDepartureToken ); switch( leg->OriginID ){ case Routed::Anchorage: dOriginAnchorage->Send( dSendData ); break; case Routed::Cupertino: dOriginCupertino->Send( dSendData ); break; case Routed::Noida: dOriginNoida ->Send( dSendData ); break; case Routed::SealBeach: dOriginSealBeach->Send( dSendData ); break; case Routed::UK: dOriginUK ->Send( dSendData ); break; case Routed::Waltham: dOriginWaltham ->Send( dSendData ); break; default: // Huh ? assert(0); } } //--------------------------------------------------------- // ::loadRouteThread() - Load a route to a RouteMap hub // // Description johnS 10-4-2000 // ----------- // This method sends a route entry into a designated hub. // All routes are loaded via the Waltham origin. When // the route arrives at its designated hub, that hub loads // it into its local RouteTable. // // 'TeachRoute' Token Format // // 31 13 11 7 3 0 // ____________________________________ // | | | |dest| =0 | // +----------------+-|+--|-+--|-+----+ // | | | // | | +---------> destination ID of hub to learn route // | +--------------> learned route ID: destination to // | be associated with port ID // +------------------> port ID: port ID associated with // given route. //--------------------------------------------------------- void Scheduler::loadRouteThread(){ const Routed::Route *route = LoadRoute; // Form an 'TeachRoute' token based on the contents of the given // 'Route' record. SceMiU32 addRouteToken = (route->RouterID << 4) | (route->DestinationID << 8) | (route->PortID <<12); dSendData.Set( 0, addRouteToken ); dOriginWaltham->Send( dSendData ); } //--------------------------------------------------------- // ::replyCallback() - Handle callbacks dispatched to // destination transactor output port proxies. // // Description johnS 10-4-2000 // ----------- //--------------------------------------------------------- void Scheduler::replyCallback( void *context, const SceMiMessageData *data ){ ((Scheduler *)context)->announceArrival( data->CycleStamp(), data->Get(0) ); } //--------------------------------------------------------- // ::annourceArrival() - Handle callbacks dispatched to a // destination transactor output port proxy. // // Description johnS 10-4-2000 // ----------- // This function forms an arrival record based on the received // arrival token. It determines the arrival time based on a // calculation involving the received cycleStamp, today's date, // and the cycleStamp corresponding to today's date // (obtained from the Calender). // // 'Passenger Arrival' Token Format // // 31 27 15 11 7 3 0 // ____________________________________ // | | ... | | |dest| >0 | // +--|-+---------+--|-+--|-+--|-+--|-+ // | | | | | // | | | | +----> passenger ID // | | | +---------> destination ID // | | +--------------> layover count // | +-------------------> layover 0 ID (origin ID) // | layover 1 ID // | ... ... // +----------------------------------> layover 4 ID // //--------------------------------------------------------- void Scheduler::announceArrival( SceMiU64 cycleStamp, SceMiU32 arrivalToken ){ Routed::Date todaysDate = TodaysDate; dArrivalRecord.DateOfArrival = todaysDate.Day; dArrivalRecord.TimeOfArrival = cycleStamp - todaysDate.CycleStamp; dArrivalRecord.PassengerID = (Routed::PassengerIDs) ( arrivalToken & 0xf ); dArrivalRecord.DestinationID = (Routed::LocationIDs) ( (arrivalToken >> 4) & 0xf ); dArrivalRecord.OriginID = (Routed::LocationIDs) ( (arrivalToken >> 12) & 0xf ); dArrivalRecord.LayoverCount = (arrivalToken >> 8) & 0xf ; assert( dArrivalRecord.LayoverCount < 5 ); arrivalToken >>= 16; for( unsigned i=0; i>= 4; } AnnounceArrival = &dArrivalRecord; }