All the schedulers developed by users have to inherit from the UserScheduler class. This class furnishes the methods to load its subclasses as a Scheduler class for DIET without error. The only method a user has to overload is the aggregate method. Several useful functions and macros are defined in the UserScheduler.hh file. The UserScheduler class is defined as follows:
class UserScheduler : public GlobalScheduler { typedef GlobalScheduler* constructor(); typedef void destructor(UserScheduler*); public: static const char* stName; UserScheduler(); virtual ~UserScheduler(); /** These methods are used to load the user module and to obtain an instance of the scheduler. */ static UserScheduler* getInstance(const char* moduleName); static GlobalScheduler * instanciate(const char* moduleName); void destroy(GlobalScheduler* scheduler); static GlobalScheduler* deserialize(const char* serializedScheduler, const char* moduleName); static char* serialize(GlobalScheduler* GS); /** The method that has to be overloaded to define a new scheduler. */ virtual int aggregate(corba_response_t* aggrResp, size_t max_srv, const size_t nb_responses, const corba_response_t* responses); private: /** The UserScheduler class is a singleton class. Its constructor is private. */ UserScheduler(const char* moduleName); static UserScheduler* instance; void* module; /** These two methods are obtained from the loaded module. */ constructor* constructs; destructor* destroys; };
The aggregate method takes 4 arguments:
The corba_response_t structure is defined as follows:
struct corba_response_t { typedef _CORBA_ConstrType_Variable_Var<corba_response_t> _var_type; CORBA::ULong reqID; CORBA::Long myID; SeqServerEstimation_t servers; void operator>>= (cdrStream &) const; void operator<<= (cdrStream &); };
The _var_type field is an internal CORBA object. The scheduler developer does not have to use it. The two operators operator and operator can be ignored too.
The corba_server_estimation_t is defined as follows:
struct corba_server_estimation_t { typedef _CORBA_ConstrType_Variable_Var<corba_server_estimation_t> _var_type; corba_server_t loc; corba_estimation_t estim; void operator>>= (cdrStream &) const; void operator<<= (cdrStream &); };
The corba_server_t loc structure is defined as follows:
struct corba_server_t { typedef _CORBA_ConstrType_Variable_Var<corba_server_t> _var_type; _CORBA_ObjRef_Member< _objref_SeD, SeD_Helper> ior; CORBA::String_member hostName; CORBA::Long port; void operator>>= (cdrStream &) const; void operator<<= (cdrStream &); };The two interesting fields are:
The corba_estimation_t structure is defined as follows:
struct corba_estimation_t { typedef _CORBA_ConstrType_Variable_Var<corba_estimation_t> _var_type; SeqEstValue_t estValues; void operator>>= (cdrStream &) const; void operator<<= (cdrStream &); };SeqEstValue_t estValues: This field is a CORBA sequence of estimation values. These estimation values are accessed through the specific functions: diet_est_get_internal and
These functions prototypes are:
double diet_est_get_internal(estVectorConst_t ev, int tag, double errVal); double diet_est_array_get_internal(estVectorConst_t ev, int tag, int idx, double errVal);
The tag argument may be assigned one of the following values:
To make the new scheduler class loadable by the GlobalScheduler class, the developer has to define these two functions outside the class definition:
extern "C" GlobalScheduler* constructor() { return new MyScheduler(); } extern "C" void destructor(UserScheduler* scheduler) { delete scheduler; }No C++ implementation of dynamic class loading are defined in the C++ standard. So, the UserScheduler class has to use C functions to load an external module containing the new scheduler class. A macro defined in UserScheduler.hh automates this declaration. You can simply define your class as a scheduler class by calling SCHEDULER_CLASS(MyScheduler), where MyScheduler is the name of the class which inherits of the UserScheduler class.