-SUBDIRS=contract
+SUBDIRS=contract sa
bin_PROGRAMS += fcb
{
struct fres_contract *dst;
+ if (!src) goto err;
dst = malloc(sizeof(*dst));
if (!dst) goto err;
memcpy(dst, src, sizeof(*dst));
#include <ul_gavl.h>
#include <fres_contract_type.h>
#include <fres_contract_idl.h>
+#include <forb/server_id.h>
struct fres_contract {
fres_contract_id_t id;
struct fres_container *container; /**< Pointer to the container (opaque type). */
};
+static inline int fres_contract_id_cmp(const fres_contract_id_t *a,
+ const fres_contract_id_t *b)
+{
+ return forb_server_id_cmp((forb_server_id*)a,
+ (forb_server_id*)b);
+}
+
struct fres_contract *fres_contract_new(void);
void fres_contract_destroy(struct fres_contract *contract);
struct fres_contract *fres_contract_duplicate(struct fres_contract *src);
module contract {
/// Pointer to the contract type
native ptr;
+
+ typedef sequence<ptr> ptr_seq;
/// Globaly unique contract ID
struct id_t {
char byte[8];
};
+
+ typedef sequence<id_t> id_seq;
+
};
};
schedulers /* cust_root_node */, \
node /* cust_item_node */, \
app /* cust_item_key */, \
- forb_server_id_cmp /* cust_cmp_fnc */)
+ fres_contract_id_cmp /* cust_cmp_fnc */)
GAVL_CUST_NODE_INT_IMP(fcb_sched /* cust_prefix */, \
struct res_mng /* cust_root_t */, \
struct res_key res_key;
struct res_mng *rm;
struct res_sched *rs;
- fres_contract_ptr contract2;
int ret;
forb_server_id app;
+ fres_contract_ptr contract_seq_buf;
+ fres_contract_ptr_seq contracts;
+ fres_contract_ptr_seq *contracts_sched;
+ fres_contract_id_seq ids;
+
res = fres_contract_get_resource(contract);
if (!res) {
}
- ret = fres_resource_manager_reserve_contract(rm->rm, contract, ev);
+ /* Reserve contract */
+ contracts._length = 1;
+ contract_seq_buf = contract;
+ contracts._buffer = &contract_seq_buf;
+ ret = fres_resource_manager_reserve_contracts(rm->rm, &contracts, ev);
if (forb_exception_occured(ev)) {
goto err;
}
ul_logmsg("Contract was not accepted\n");
goto err;
}
-
- ret = fres_resource_manager_commit_contract(rm->rm, id, &contract2, ev);
+
+ /* Commit contract */
+ ids._length = 1;
+ ids._buffer = id;
+ fres_resource_manager_commit_contracts(rm->rm, &ids, &contracts_sched, ev);
if (forb_exception_occured(ev)) {
goto err;
}
- ret = fres_resource_scheduler_create_vres(rs->rs, contract2, ev);
+ /* Create VRes */
+ ret = fres_resource_scheduler_create_vres(rs->rs, contracts_sched->_buffer[0], ev);
+ if (CORBA_sequence_get_release(contracts_sched)) forb_free(contracts_sched->_buffer);
+ forb_free(contracts_sched);
if (forb_exception_occured(ev)) {
goto err;
}
module fres {
interface resource_manager {
- long reserve_contract(in fres::contract::ptr contract);
- long commit_contract(in fres::contract::id_t id, out fres::contract::ptr contract_with_scheduler_data);
- long cancel_contract(in fres::contract::id_t id);
+ long reserve_contracts(in contract::ptr_seq contracts);
+ void commit_contracts(in contract::id_seq ids,
+ out contract::ptr_seq contract_with_scheduler_data);
+ void cancel_contracts(in contract::id_seq ids);
};
};
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+include_HEADERS = fres_sa_scenario.h
+
+shared_LIBRARIES = fres_sa
+
+fres_sa_SOURCES = fres_sa_scenario.c
--- /dev/null
+#include "fres_sa_scenario.h"
+
+struct fres_sa_contract *
+fres_sa_contract_new(void)
+{
+ struct fres_sa_contract *c;
+
+ c = malloc(sizeof(*c));
+ if (!c) goto err;
+
+ memset(c, 0, sizeof(*c));
+ return c;
+err:
+ return NULL;
+}
+
+void
+fres_sa_contract_destroy(struct fres_sa_contract *c)
+{
+ if (c) {
+ if (c->contract) {
+ fres_contract_destroy(c->contract);
+ }
+ free(c->priv);
+ free(c);
+ }
+}
+
+/**
+ * Duplicates SA contract. It doesn't duplicate @a priv field.
+ *
+ * @param src
+ *
+ * @return Duplicate or NULL in case of error.
+ */
+struct fres_sa_contract *
+fres_sa_contract_duplicate(struct fres_sa_contract *src)
+{
+ struct fres_sa_contract *dst;
+
+ dst = fres_sa_contract_new();
+ if (!dst) goto err;
+
+ dst->status = src->status;
+ dst->contract = fres_contract_duplicate(src->contract);
+
+ return dst;
+err:
+ return NULL;
+}
+
+
+GAVL_CUST_NODE_INT_IMP(fres_sa_scenario_contract /* cust_prefix */,
+ struct fres_sa_scenario /* cust_root_t */,
+ struct fres_sa_contract /* cust_item_t */,
+ fres_contract_id_t /* cust_key_t */,
+ contracts /* cust_root_node */,
+ node /* cust_item_node */,
+ contract->id /* cust_item_key */,
+ fres_contract_id_cmp /* cust_cmp_fnc */)
+
+struct fres_sa_scenario *
+fres_sa_scenario_new(void)
+{
+ struct fres_sa_scenario *s;
+
+ s = malloc(sizeof(*s));
+ if (!s) return NULL;
+
+ memset(s, 0, sizeof(*s));
+
+ return s;
+}
+
+void fres_sa_scenario_destroy(struct fres_sa_scenario *scenario)
+{
+ struct fres_sa_contract *c;
+ gavl_cust_for_each_cut(fres_sa_scenario_contract,
+ scenario, c) {
+ fres_sa_contract_destroy(c);
+ }
+}
+
+struct fres_sa_scenario *
+fres_sa_scenario_duplicate(struct fres_sa_scenario *src)
+{
+ struct fres_sa_scenario *dst;
+ struct fres_sa_contract *c1, *c2;
+
+ if (!src) goto err;
+ dst = fres_sa_scenario_new();
+ if (!dst) goto err;
+
+ gavl_cust_for_each_cut(fres_sa_scenario_contract,
+ src, c1) {
+ c2 = fres_sa_contract_duplicate(c1);
+ if (!c2) goto free_err;
+ fres_sa_scenario_contract_insert(dst, c2);
+ }
+
+ return dst;
+free_err:
+ fres_sa_scenario_destroy(dst);
+err:
+ return NULL;
+}
+
+int fres_sa_scenario_add_contract(struct fres_sa_scenario *scenario,
+ struct fres_contract *contract)
+{
+ int ret = -1;
+ struct fres_sa_contract *sac;
+
+ sac = fres_sa_contract_new();
+ if (!sac) goto err;
+
+ sac->status = FRES_SA_CONTRACT_NEW;
+ sac->contract = contract;
+
+ fres_sa_scenario_contract_insert(scenario, sac);
+ scenario->num_contracts ++;
+
+ return 0;
+err:
+ return ret;
+}
+
+int fres_sa_scenario_del_contract(struct fres_sa_scenario *scenario,
+ fres_contract_id_t *id)
+{
+ struct fres_sa_contract *c;
+ c = fres_sa_scenario_contract_find(scenario, id);
+ if (c) {
+ scenario->num_contracts--;
+ fres_sa_scenario_contract_delete(scenario, c);
+ return 1;
+ }
+ return 0;
+}
--- /dev/null
+#ifndef FRES_SA_SCENARIO_H
+#define FRES_SA_SCENARIO_H
+
+#include <fres_contract.h>
+#include <ul_gavlcust.h>
+
+enum fres_sa_contract_status {
+ FRES_SA_CONTRACT_NEW,
+ FRES_SA_CONTRACT_RESERVED,
+ FRES_SA_CONTRACT_COMMITED
+};
+
+/**
+ * Represenation of a contract in a scenario.
+ *
+ */
+struct fres_sa_contract {
+ enum fres_sa_contract_status status;
+ struct fres_contract *contract;
+ void *priv; /**< Private data for use by admission test */
+ gavl_node_t node;
+};
+
+struct fres_sa_scenario {
+ gavl_cust_root_field_t contracts;
+ unsigned num_contracts; /**< The number if contracts in scenario */
+ void *priv;
+};
+
+
+GAVL_CUST_NODE_INT_DEC(fres_sa_scenario_contract /* cust_prefix */,
+ struct fres_sa_scenario /* cust_root_t */,
+ struct fres_sa_contract /* cust_item_t */,
+ fres_contract_id_t /* cust_key_t */,
+ contracts /* cust_root_node */,
+ node /* cust_item_node */,
+ contract->id /* cust_item_key */,
+ fres_contract_id_cmp /* cust_cmp_fnc */)
+
+struct fres_sa_contract *
+fres_sa_contract_new(void);
+
+void
+fres_sa_contract_destroy(struct fres_sa_contract *sa_contract);
+
+struct fres_sa_contract *
+fres_sa_contract_duplicate(struct fres_sa_contract *sa_contract);
+
+struct fres_sa_scenario *
+fres_sa_scenario_new(void);
+
+void fres_sa_scenario_destroy(struct fres_sa_scenario *scenario);
+
+struct fres_sa_scenario *
+fres_sa_scenario_duplicate(struct fres_sa_scenario *scenario);
+
+int fres_sa_scenario_add_contract(struct fres_sa_scenario *scenario,
+ struct fres_contract *contract);
+
+
+
+#endif
--- /dev/null
+# Generic directory or leaf node makefile for OCERA make framework
+
+ifndef MAKERULES_DIR
+MAKERULES_DIR := $(shell ( old_pwd="" ; while [ ! -e Makefile.rules ] ; do if [ "$$old_pwd" = `pwd` ] ; then exit 1 ; else old_pwd=`pwd` ; cd -L .. 2>/dev/null ; fi ; done ; pwd ) )
+endif
+
+ifeq ($(MAKERULES_DIR),)
+all : default
+.DEFAULT::
+ @echo -e "\nThe Makefile.rules has not been found in this or partent directory\n"
+else
+include $(MAKERULES_DIR)/Makefile.rules
+endif
+
--- /dev/null
+bin_PROGRAMS = frm_dummy
+shared_LIBRARIES = frs_dummy
+
+frm_dummy_SOURCES = frm_dummy.c
+frm_dummy_LIBS = frm fres_sa forb contract fosa rt ulut
+
+frs_dummy_SOURCES = frs_dummy.c
+frs_dummy_LIBS = frs
--- /dev/null
+#include <frm.h>
+#include <forb.h>
+#include <error.h>
+#include <errno.h>
+#include <fres_sa_scenario.h>
+#include <stdbool.h>
+#include <fcb.h>
+
+bool admission_test(struct fres_sa_scenario *scenario)
+{
+ bool schedulable;
+
+ 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;
+
+ 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;
+
+ 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_contract_find(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);
+
+ for (i=0; i<ids->_length; i++) {
+ struct fres_sa_contract *c;
+ c = fres_sa_scenario_contract_find(frm->running, &ids->_buffer[i]);
+
+ if (c) {
+ fres_sa_scenario_contract_delete(frm->running, c);
+ }
+ }
+}
+
+
+const struct forb_fres_resource_manager_impl 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 frm_data dummy_data;
+
+ 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, &impl, &dummy_data);
+ if (!frm) error(1, errno, "forb_fres_resource_manager_new");
+
+ forb_execute_object(frm);
+
+ return 0;
+}
--- /dev/null
+#include <frs.h>