--- /dev/null
+////////////////////////////////////////////////////////////////////////////
+// ---------------------------------------------------------------------- //
+// Copyright (C) 2006 - 2008 FRESCOR consortium partners: //
+// //
+// Universidad de Cantabria, SPAIN //
+// University of York, UK //
+// Scuola Superiore Sant'Anna, ITALY //
+// Kaiserslautern University, GERMANY //
+// Univ. Politécnica Valencia, SPAIN //
+// Czech Technical University in Prague, CZECH REPUBLIC //
+// ENEA SWEDEN //
+// Thales Communication S.A. FRANCE //
+// Visual Tools S.A. SPAIN //
+// Rapita Systems Ltd UK //
+// Evidence ITALY //
+// //
+// See http://www.frescor.org for a link to partners' websites //
+// //
+// FRESCOR project (FP6/2005/IST/5-034026) is funded //
+// in part by the European Union Sixth Framework Programme //
+// The European Union is not liable of any use that may be //
+// made of this code. //
+// //
+// //
+// based on previous work (FSF) done in the FIRST project //
+// //
+// Copyright (C) 2005 Mälardalen University, SWEDEN //
+// Scuola Superiore S.Anna, ITALY //
+// Universidad de Cantabria, SPAIN //
+// University of York, UK //
+// //
+// FSF API web pages: http:marte.unican.es/fsf/docs //
+// http:shark.sssup.it/contrib/first/docs/ //
+// //
+// This file is part of FORB (Frescor Object Request Broker) //
+// //
+// FORB is free software; you can redistribute it and/or modify it //
+// under terms of the GNU General Public License as published by the //
+// Free Software Foundation; either version 2, or (at your option) any //
+// later version. FORB is distributed in the hope that it will be //
+// useful, but WITHOUT ANY WARRANTY; without even the implied warranty //
+// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU //
+// General Public License for more details. You should have received a //
+// copy of the GNU General Public License along with FORB; see file //
+// COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, //
+// Cambridge, MA 02139, USA. //
+// //
+// As a special exception, including FORB header files in a file, //
+// instantiating FORB generics or templates, or linking other files //
+// with FORB objects to produce an executable application, does not //
+// by itself cause the resulting executable application to be covered //
+// by the GNU General Public License. This exception does not //
+// however invalidate any other reasons why the executable file might be //
+// covered by the GNU Public License. //
+////////////////////////////////////////////////////////////////////////////
+
+#ifndef _CM_IDL
+#define _CM_IDL
+
+#include "contract/fres_contract_idl.idl"
+#include "contract/fres_blocks.idl"
+#include "frm.idl"
+#include "frs.idl"
+
+module fres {
+ interface contract_broker {
+ const string reg_name = "fcb";
+ /**
+ * Registers a resource manager with the contract broker
+ *
+ * @param restype
+ * @param resid
+ * @param rm_obj
+ *
+ * @return Zero on success, non-zero error code on error.
+ */
+ long register_manager(in frsh_resource_type_t restype,
+ in frsh_resource_id_t resid,
+ in resource_manager rm_obj);
+
+ /**
+ * Registers a resource scheduler with the contract broker
+ *
+ * @param restype
+ * @param resid
+ * @param rs_obj
+ *
+ * @return Zero on success, non-zero error code on error.
+ */
+ long register_scheduler(in frsh_resource_type_t restype,
+ in frsh_resource_id_t resid,
+ in resource_scheduler rs_obj);
+
+
+ /**
+ * Tries to negotiate a contract
+ *
+ * @param[in] contract Contract to negotiate
+ *
+ * @param[out] id Global ID of the contract if
+ * negotiation was successful.
+ *
+ * @return Zero if the contract was successfully
+ * negotiated, non-zero code on error or when
+ * negotiation failed.
+ */
+ long negotiate_contract(in contract::ptr contract, out fres::contract::id_t id);
+ };
+};
+
+#endif
shared_LIBRARIES = frm
-frm_SOURCES = fres_sa_scenario.c
+frm_SOURCES = fres_sa_scenario.c frm_generic.c
frm_SERVER_IDL = frm.idl
+include_HEADERS += frm_generic.h fres_sa_scenario.h
include_GEN_HEADERS += frm.h
-include_HEADERS = fres_sa_scenario.h
lib_LIBRARIES += frm_client
frm_client_CLIENT_IDL = frm.idl
-#ifndef _RM_IDL
-#define _RM_IDL
+#ifndef _FRM_IDL
+#define _FRM_IDL
#include "../contract/fres_contract_idl.idl"
--- /dev/null
+#include <frm_generic.h>
+#include <forb.h>
+#include <ul_log.h>
+#include <fres_sa_scenario.h>
+#include <fcb.h>
+
+UL_LOG_CUST(ulogd_frm);
+ul_log_domain_t ulogd_frm = {UL_LOGL_MSG, "frm"};
+
+struct frm_data {
+ struct fres_sa_scenario *running;
+ frm_adm_test_fnc_t admission_test;
+ void *priv;
+};
+
+#define object_to_frm(o) (struct frm_data*)forb_instance_data(o)
+#define save_errno(cmd) do { int _e = errno; cmd; errno = _e; } while(0)
+
+static CORBA_long reserve_contracts(fres_resource_manager obj,
+ const fres_contract_ptr_seq* contracts,
+ CORBA_Environment *ev)
+{
+ struct frm_data *frm = object_to_frm(obj);
+ struct fres_sa_scenario *prospective;
+ struct fres_contract *c;
+ bool schedulable;
+ int i;
+
+ ul_logdeb("reserve_contracts\n");
+
+ prospective = fres_sa_scenario_duplicate(frm->running);
+ for (i=0; i<contracts->_length; i++) {
+ c = fres_contract_duplicate(contracts->_buffer[i]);
+ fres_sa_scenario_add_contract(prospective, c);
+ }
+
+ schedulable = frm->admission_test(prospective, frm->priv);
+
+ if (schedulable) {
+ fres_sa_scenario_destroy(frm->running);
+ frm->running = prospective;
+ } else {
+ fres_sa_scenario_destroy(prospective);
+ }
+ return schedulable ? 0 : 1;
+}
+
+static void commit_contracts(fres_resource_manager obj,
+ const fres_contract_id_seq* ids,
+ fres_contract_ptr_seq** contract_with_scheduler_data,
+ CORBA_Environment *ev)
+{
+ struct frm_data *frm = object_to_frm(obj);
+ int i, num;
+ struct fres_sa_contract *c;
+ fres_contract_ptr_seq *contracts;
+
+ ul_logdeb("commit_contracts\n");
+
+ contracts = forb_malloc(sizeof(*contracts));
+ if (!contracts) {
+ ev->major = FORB_EX_NO_MEMORY;
+ goto err;
+ }
+ num = ids->_length;
+ contracts->_buffer = CORBA_sequence_fres_contract_ptr_allocbuf(num);
+ contracts->_maximum = contracts->_length = num;
+
+ for (i=0; i < num; i++) {
+ c = fres_sa_scenario_find_contract(frm->running, &ids->_buffer[i]);
+ }
+
+ *contract_with_scheduler_data = contracts;
+err:;
+}
+
+static void cancel_contracts(fres_resource_manager obj,
+ const fres_contract_id_seq* ids,
+ CORBA_Environment *ev)
+{
+ int i;
+ struct frm_data *frm = object_to_frm(obj);
+
+ ul_logdeb("cancel_contracts\n");
+
+ for (i=0; i<ids->_length; i++) {
+ struct fres_sa_contract *c;
+ c = fres_sa_scenario_find_contract(frm->running, &ids->_buffer[i]);
+
+ if (c) {
+ fres_sa_scenario_del_contract(frm->running, c);
+ }
+ }
+}
+
+
+static const struct forb_fres_resource_manager_impl frm_impl = {
+ .reserve_contracts = reserve_contracts,
+ .commit_contracts = commit_contracts,
+ .cancel_contracts = cancel_contracts,
+};
+
+/**
+ * Initializes and runs a generic resource manager. The only thing a
+ * caller has to supply is admission test function, which is passed in
+ * @a frm_data->admission_test.
+ *
+ * @param orb FORB object used to communicate with other components.
+ * @param admission_test Admission test function.
+ * @param priv Pointer to passed as priv parameter to frm_adm_test_fnc_t.
+ *
+ * @return
+ */
+int frm_generic_run(forb_orb orb, frm_adm_test_fnc_t admission_test, void *priv)
+{
+ fres_contract_broker fcb;
+ fres_resource_manager frm;
+ struct forb_env env;
+ struct frm_data frm_data;
+
+ memset(&frm_data, 0, sizeof(frm_data));
+ frm_data.admission_test = admission_test;
+ frm_data.priv = priv;
+
+ fcb = forb_resolve_reference(orb, fres_contract_broker_reg_name);
+ if (!fcb) {
+ save_errno(ul_logerr("Could not find contract broker"));
+ goto err;
+ }
+
+ frm = forb_fres_resource_manager_new(orb, &frm_impl, &frm_data);
+ if (!frm) {
+ save_errno(ul_logerr("forb_fres_resource_manager_new error"));
+ goto err_release_fcb;
+ }
+
+ fres_contract_broker_register_manager(fcb, FRSH_RT_PROCESSOR, 0,
+ frm, &env);
+ if (forb_exception_occured(&env)) {
+ goto err_release_frm;
+ }
+
+ forb_execute_object(frm);
+ return 0;
+
+err_release_frm:
+ forb_object_release(frm);
+err_release_fcb:
+ forb_object_release(fcb);
+err:
+ return -1;
+}
--- /dev/null
+#ifndef FRM_GENERIC_H
+#define FRM_GENERIC_H
+
+#include <frm.h>
+#include <fres_sa_scenario.h>
+
+/**
+ * Admission test for a given resource.
+ *
+ * The admission test has to evaluate schedulability of the scenario
+ * given as a parameter. It can use
+ * fres_sa_scenario_for_each_contract() macro to traverse through all
+ * the contracts in the scenario. No constract should be added or
+ * deleted, but any data (blocks) can be added to the contracts. If
+ * the scenario is schedulable, the contracts (with possibly added
+ * data) are sent to resource scheduler, which can use this additional
+ * data as parameters for VRes creation.
+ *
+ * @param scenario Scenario to check its schedulability.
+ * @param priv Pointer to private data, registered by frm_generic_run().
+ *
+ * @return True if the scenario ia schedulable, false otherwise.
+ */
+typedef bool (*frm_adm_test_fnc_t)(struct fres_sa_scenario *scenario, void *priv);
+
+int frm_generic_run(forb_orb orb, frm_adm_test_fnc_t admission_test, void *priv);
+
+#endif
-#include <frm.h>
+#include <frm_generic.h>
#include <forb.h>
#include <error.h>
#include <errno.h>
#include <fres_sa_scenario.h>
#include <stdbool.h>
-#include <fcb.h>
#include <ul_log.h>
UL_LOG_CUST(ulogd_frm_dummy);
ul_log_domain_t ulogd_frm_dummy = {UL_LOGL_MSG, "frm_dummy"};
+struct dummy_data {
+ int some_data;
+};
+
-bool admission_test(struct fres_sa_scenario *scenario)
+bool admission_test(struct fres_sa_scenario *scenario, void *priv)
{
bool schedulable;
+ struct dummy_data *data = priv;
ul_logmsg("Admission test");
+ data->some_data++;
schedulable = scenario->num_contracts <= 3;
return schedulable;
}
-struct frm_data {
- bool (*admission_test)(struct fres_sa_scenario *scenario);
- struct fres_sa_scenario *running;
-};
-
-#define object_to_frm(o) (struct frm_data*)forb_instance_data(o)
-
-CORBA_long reserve_contracts(fres_resource_manager obj,
- const fres_contract_ptr_seq* contracts,
- CORBA_Environment *ev)
-{
- struct frm_data *frm = object_to_frm(obj);
- struct fres_sa_scenario *prospective;
- struct fres_contract *c;
- bool schedulable;
- int i;
-
- ul_logdeb("reserve_contracts\n");
-
- prospective = fres_sa_scenario_duplicate(frm->running);
- for (i=0; i<contracts->_length; i++) {
- c = fres_contract_duplicate(contracts->_buffer[i]);
- fres_sa_scenario_add_contract(prospective, c);
- }
-
- schedulable = frm->admission_test(prospective);
-
- if (schedulable) {
- fres_sa_scenario_destroy(frm->running);
- frm->running = prospective;
- } else {
- fres_sa_scenario_destroy(prospective);
- }
- return schedulable ? 0 : 1;
-}
-
-void commit_contracts(fres_resource_manager obj,
- const fres_contract_id_seq* ids,
- fres_contract_ptr_seq** contract_with_scheduler_data,
- CORBA_Environment *ev)
-{
- struct frm_data *frm = object_to_frm(obj);
- int i, num;
- struct fres_sa_contract *c;
- fres_contract_ptr_seq *contracts;
-
- ul_logdeb("commit_contracts\n");
-
- contracts = forb_malloc(sizeof(*contracts));
- if (!contracts) {
- ev->major = FORB_EX_NO_MEMORY;
- goto err;
- }
- num = ids->_length;
- contracts->_buffer = CORBA_sequence_fres_contract_ptr_allocbuf(num);
- contracts->_maximum = contracts->_length = num;
-
- for (i=0; i < num; i++) {
- c = fres_sa_scenario_find_contract(frm->running, &ids->_buffer[i]);
- }
-
- *contract_with_scheduler_data = contracts;
-err:;
-}
-
-void cancel_contracts(fres_resource_manager obj,
- const fres_contract_id_seq* ids,
- CORBA_Environment *ev)
-{
- int i;
- struct frm_data *frm = object_to_frm(obj);
-
- ul_logdeb("cancel_contracts\n");
-
- for (i=0; i<ids->_length; i++) {
- struct fres_sa_contract *c;
- c = fres_sa_scenario_find_contract(frm->running, &ids->_buffer[i]);
-
- if (c) {
- fres_sa_scenario_del_contract(frm->running, c);
- }
- }
-}
-
-
-const struct forb_fres_resource_manager_impl dummy_impl = {
- .reserve_contracts = reserve_contracts,
- .commit_contracts = commit_contracts,
- .cancel_contracts = cancel_contracts,
-};
int main(int argc, char *argv[])
{
forb_orb orb;
- fres_contract_broker fcb;
- fres_resource_manager frm;
- struct forb_env env;
-
- struct frm_data dummy_data;
+ struct dummy_data dummy_data;
+ int ret;
orb = forb_init(&argc, &argv, "frm_dummy");
if (!orb) error(1, errno, "forb_init");
- fcb = forb_resolve_reference(orb, fres_contract_broker_reg_name);
- if (!fcb) error(1, 0, "Could not find contract broker");
-
- frm = forb_fres_resource_manager_new(orb, &dummy_impl, &dummy_data);
- if (!frm) error(1, errno, "forb_fres_resource_manager_new");
+ ret = frm_generic_run(orb, admission_test, &dummy_data);
- fres_contract_broker_register_manager(fcb, FRSH_RT_PROCESSOR, 0,
- frm, &env);
-
- forb_execute_object(frm);
+ if (ret != 0) {
+ error(1, errno, "frm_generic_run");
+ }
return 0;
}