The UserScheduler class

This section presents how the scheduling process is managed in DIET. Most of the developers can go directly to the next section.

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*);

  static const char* stName;
  /** 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);

  GlobalScheduler* deserialize(const char* serializedScheduler,
			       const char* moduleName);
  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);

  /** 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. Accessing the values in each corba_estimation_t instance is done with the functions described in section 9.3.4

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.

The DIET Team - Mer 29 nov 2017 15:13:36 EST