shared_LIBRARIES += fra
-fra_SOURCES = fra_generic.c fres_vres.c
+fra_SOURCES = fra_generic.c fra_registry.c fres_vres.c
fra_SERVER_IDL = fra.idl
include_GEN_HEADERS += fra.h
include_HEADERS = fra_generic.h fres_vres.h
return NULL;
}
-
-/**
- * Creates and registeres the allocator with contract broker.
- *
- * @param orb
- * @param fcb
- *
- * @param executor Executor which will execute requests for this fres
- * allocator.
- *
- * @param allocator
- *
- * @return Zero on success, -1 on error.
- */
-int fra_register(forb_orb orb,
- fres_contract_broker fcb,
- forb_executor_t *executor,
- struct fres_allocator *allocator)
-{
- int ret;
- struct forb_env env;
- fres_resource_allocator fra;
-
- fra = fra_new(orb, executor, allocator);
- /* Register resource allocator */
- ret = fres_contract_broker_register_allocator(fcb,
- allocator->res_type,
- allocator->res_id,
- fra, &env);
- if (forb_exception_occurred(&env) || ret != 0) {
- goto err_release;
- }
- return 0;
-err_release:
- save_errno(forb_object_release(fra));
- return -1;
-}
-
/**
* Returns pointer to VRes, which corresponds to the contract with the
* given id.
*/
int (*cancel_vres)(fres_vres_t *vres, void *priv);
void *priv; /**< Pointer to allocator's private data */
+
+ /**
+ * A callback called whenever the resource allocator is to be
+ * activated by fra_activate().
+ */
+ int (*activate_callback)(forb_orb orb);
};
fres_resource_allocator fra_new(forb_orb orb,
forb_executor_t *executor,
struct fres_allocator *allocator);
-int fra_register(forb_orb orb,
- fres_contract_broker fcb,
- forb_executor_t *executor,
- struct fres_allocator *allocator);
+void fra_registry_init(forb_orb orb,
+ fres_contract_broker fcb,
+ forb_executor_t *executor);
+int fra_register(struct fres_allocator *allocator);
+int fra_activate(frsh_resource_type_t res_type,
+ frsh_resource_id_t res_id);
fres_vres_t *fra_get_vres(fres_contract_id_t *id);
--- /dev/null
+/**
+ * @file fra_registry.c
+ * @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * @date Thu Oct 23 15:26:19 2008
+ *
+ * @brief Registry of FRES Resource Allocator
+ *
+ *
+ */
+#include <forb.h>
+#include <fra.h>
+#include <fcb.h>
+#include <ul_log.h>
+#include <ul_gavlcust.h>
+#include "fra_generic.h"
+#include <stdbool.h>
+
+UL_LOG_CUST(ulogd_fra_registry);
+ul_log_domain_t ulogd_fra_registry = {UL_LOGL_MSG, "fra_registry"};
+
+#define save_errno(cmd) do { int _e = errno; cmd; errno = _e; } while(0)
+
+struct registered_allocator {
+ gavl_node_t node;
+ struct fres_allocator *allocator;
+ bool registered_with_fcb;
+};
+
+#define FRA_MAX_ALLOCATORS 32
+static struct registered_allocator allocators[FRA_MAX_ALLOCATORS];
+static unsigned free_allocator_idx = 0;
+
+static struct registry {
+ forb_orb orb;
+ fres_contract_broker fcb;
+ forb_executor_t *executor;
+
+ gavl_cust_root_field_t allocators;
+} registry;
+
+
+static inline int fres_allocator_cmp(struct fres_allocator **a,
+ struct fres_allocator **b)
+{
+ if ((*a)->res_type < (*b)->res_type) {
+ return -1;
+ } else if ((*a)->res_type > (*b)->res_type) {
+ return +1;
+ } else if ((*a)->res_id < (*b)->res_id) {
+ return -1;
+ } else if ((*a)->res_id > (*b)->res_id) {
+ return +1;
+ } else {
+ return 0;
+ }
+}
+
+GAVL_CUST_NODE_INT_DEC(fra_registry /* cust_prefix */,
+ struct registry /* cust_root_t */,
+ struct registered_allocator /* cust_item_t */,
+ struct fres_allocator* /* cust_key_t */,
+ allocators /* cust_root_node */,
+ node /* cust_item_node */,
+ allocator /* cust_item_key */,
+ fres_allocator_cmp /* cust_cmp_fnc */);
+
+GAVL_CUST_NODE_INT_IMP(fra_registry /* cust_prefix */,
+ struct registry /* cust_root_t */,
+ struct registered_allocator /* cust_item_t */,
+ struct fres_allocator* /* cust_key_t */,
+ allocators /* cust_root_node */,
+ node /* cust_item_node */,
+ allocator /* cust_item_key */,
+ fres_allocator_cmp /* cust_cmp_fnc */);
+
+
+/**
+ * Initializes registry of resource allocators.
+ *
+ * This registry is used by fra_register() and its main purpose is to
+ * allow "late" registration of allocators to FCB. Late registration
+ * means, that the allocator is registered with FCB only when the
+ * application accesses the resource.
+ *
+ * This functionality is useful at least during testing and debugging,
+ * when it is not necessary to run all the resource managers. Only the
+ * managers for resources used by the application are required.
+ *
+ * @param orb
+ * @param fcb Contract broker object reference
+ * @param executor Executor for all allocator objects
+ */
+void fra_registry_init(forb_orb orb,
+ fres_contract_broker fcb,
+ forb_executor_t *executor)
+{
+ registry.orb = orb;
+ registry.fcb = fcb;
+ registry.executor = executor;
+
+ fra_registry_init_root_field(®istry);
+}
+
+/**
+ * Registeres the allocator in registry.
+ *
+ * @param allocator
+ *
+ * @return Zero on success, -1 on error.
+ */
+int fra_register(struct fres_allocator *allocator)
+{
+ struct registered_allocator *ra;
+ int ret;
+
+ ra = fra_registry_find(®istry, &allocator);
+ if (!ra && free_allocator_idx < FRA_MAX_ALLOCATORS) {
+ ra = &allocators[free_allocator_idx];
+ free_allocator_idx++;
+ ra->allocator = allocator;
+ ra->registered_with_fcb = false;
+ fra_registry_insert(®istry, ra);
+ ret = 0;
+ } else {
+ ret = -1;
+ }
+ return ret;
+}
+
+/**
+ * Creates FORB object reference for the allocator and registeres it
+ * with contract broker.
+ *
+ * @param allocator
+ *
+ * @return Zero on success, -1 on error.
+ */
+static int register_fra_to_fcb(struct fres_allocator *allocator)
+{
+ int ret;
+ struct forb_env env;
+ fres_resource_allocator fra;
+
+ fra = fra_new(registry.orb, registry.executor, allocator);
+
+ if (allocator->activate_callback) {
+ ret = allocator->activate_callback(registry.orb);
+ if (ret) goto err_release;
+ }
+ /* Register resource allocator */
+ ret = fres_contract_broker_register_allocator(registry.fcb,
+ allocator->res_type,
+ allocator->res_id,
+ fra, &env);
+ if (forb_exception_occurred(&env) || ret != 0) {
+ goto err_release;
+ }
+ return 0;
+err_release:
+ save_errno(forb_object_release(fra));
+ return -1;
+}
+
+/**
+ * Creates the allocator object and registeres it with contract
+ * broker. The allocator must be previously registered by
+ * fra_register(). If the allocator is already registered, this
+ * function does nothing.
+ *
+ * @param res_type
+ * @param res_id
+ *
+ * @return Zero on success, -1 on error.
+ */
+
+int fra_activate(frsh_resource_type_t res_type,
+ frsh_resource_id_t res_id)
+{
+ struct fres_allocator key, *pkey=&key;
+ struct registered_allocator *ra;
+ int ret = -1;
+
+ key.res_type = res_type;
+ key.res_id = res_id;
+ ra = fra_registry_find(®istry, &pkey);
+ if (ra) {
+ if (ra->registered_with_fcb) {
+ ret = 0;
+ } else {
+ ret = register_fra_to_fcb(ra->allocator);
+ if (ret == 0) {
+ ra->registered_with_fcb = true;
+ }
+ }
+ }
+
+ return ret;
+}
struct forb_env env;
int ret;
fres_contract_id_t id;
+ fres_block_resource *r;
+
+ /* Activate allocator */
+ r = fres_contract_get_resource(*contract);
+ if (r) {
+ fra_activate(r->resource_type,
+ r->resource_id);
+ }
+
+ /* Negotiate contract */
ret = fres_contract_broker_negotiate_contract(frsh_forb_global.fcb,
*contract,
&id, &env);
#include <frsh_core.h>
#include <fcb.h>
#include <forb.h>
+#include <fra_generic.h>
#include "frsh_forb.h"
#include <frsh_resources.h>
/* Initialize resource allocators */
ret = forb_executor_init(&frsh_forb_global.alloc_executor);
if (ret) goto err;
+
+ fra_registry_init(frsh_forb_global.orb, frsh_forb_global.fcb,
+ &frsh_forb_global.alloc_executor);
#ifdef CONFIG_AQUOSA
- ret = aqcpu_fra_init(frsh_forb_global.orb, frsh_forb_global.fcb,
- &frsh_forb_global.alloc_executor);
+ ret = aqcpu_fra_init();
if (ret) goto err;
#endif
#ifdef CONFIG_RESOURCE_DUMMY
- ret = fra_dummy_init(frsh_forb_global.orb, frsh_forb_global.fcb,
- &frsh_forb_global.alloc_executor);
+ ret = fra_dummy_init();
if (ret) goto err;
#endif
#endif
#ifdef CONFIG_RESOURCE_ITEM
- ret = fra_item_init(frsh_forb_global.orb, frsh_forb_global.fcb,
- &frsh_forb_global.alloc_executor);
+ ret = fra_item_init();
if (ret) goto err;
#endif
/* Run resource allocators */
* FRSH_ERR_ALREADY_INITIALIZED
* FRSH_ERR_INTERNAL_ERROR (something, different from the previous case, gone wrong)
*/
-int aqcpu_fra_init(forb_orb orb, fres_contract_broker fcb, forb_executor_t *executor)
+int aqcpu_fra_init(void)
{
qos_rv qrv;
int rv;
return -1;
}
- if ((rv = fra_register(orb, fcb, executor, &aqcpu_allocator))) {
+ if ((rv = fra_register(&aqcpu_allocator))) {
qres_cleanup();
return rv;
}
#include <fcb.h>
#include <frsh_core.h>
-int aqcpu_fra_init(forb_orb orb, fres_contract_broker fcb, forb_executor_t *executor);
+int aqcpu_fra_init(void);
#endif /* AQCPU_RES_H */
.priv = &my_data
};
-int fra_dummy_init(forb_orb orb, fres_contract_broker fcb, forb_executor_t *executor)
+int fra_dummy_init(void)
{
fres_block_register_dummy();
- return fra_register(orb, fcb, executor, &dummy_allocator);
+ return fra_register(&dummy_allocator);
}
#define DUMMY_RESOURCE_TYPE 255
#define DUMMY_RESOURCE_ID 255
-int fra_dummy_init(forb_orb orb, fres_contract_broker fcb, forb_executor_t *executor);
+int fra_dummy_init(void);
int fres_block_register_dummy(void);
/* Define fres_container_(add|get|del)_dummy_sched. */
#include <fra_generic.h>
#include <stdio.h>
#include <frsh_distributed.h>
+#include <frsh_forb.h>
UL_LOG_CUST(ulogd_frs_item);
ul_log_domain_t ulogd_frs_item = {UL_LOGL_MSG, "frs_item"};
return FRSH_ERR_NOT_IMPLEMENTED;
}
-
-
static struct item item;
+int initialize_item_scheduler(forb_orb orb)
+{
+ item.scheduler = forb_resolve_reference(frsh_forb_global.orb, "item_scheduler");
+ if (!item.scheduler) {
+ ul_logerr("forb_resolve_reference(item_scheduler) failed\n");
+ return errno;
+ }
+ return 0;
+}
+
static struct fres_allocator item_allocator = {
.res_type = FRSH_RT_NETWORK,
.res_id = FRSH_NETPF_ITEM,
.create_vres = create_vres,
.cancel_vres = cancel_vres,
.change_vres = change_vres,
- .priv = &item
+ .priv = &item,
+ .activate_callback = initialize_item_scheduler,
};
-int fra_item_init(forb_orb orb, fres_contract_broker fcb, forb_executor_t *executor)
+int fra_item_init(void)
{
fres_block_register_item();
-
- item.scheduler = forb_resolve_reference(orb, "item_scheduler");
- if (!item.scheduler) {
- ul_logerr("forb_resolve_reference(item_scheduler) failed\n");
- return errno;
- }
- return fra_register(orb, fcb, executor, &item_allocator);
+ return fra_register(&item_allocator);
}
/**
#include <fres_container.h>
int fres_block_register_item();
-int fra_item_init(forb_orb orb, fres_contract_broker fcb, forb_executor_t *executor);
+int fra_item_init(void);
int fra_item_receive(frsh_vres_id_t vres, unsigned *data[]);
/* Define fres_container_(add|get|del)_item_nodes. */