]> rtime.felk.cvut.cz Git - frescor/frsh.git/commitdiff
Added "late" registration of allocators
authorMichal Sojka <sojkam1@fel.cvut.cz>
Wed, 10 Dec 2008 21:17:35 +0000 (22:17 +0100)
committerMichal Sojka <sojkam1@fel.cvut.cz>
Wed, 10 Dec 2008 21:17:35 +0000 (22:17 +0100)
Thank to this, it is not required to run managers for all compiled-in
resources, but only those which are really needed by the applications.

The allocator is registered to the contract broker just before the first
contract for a given resource is negotiated.

12 files changed:
fres/resalloc/Makefile.omk
fres/resalloc/fra_generic.c
fres/resalloc/fra_generic.h
fres/resalloc/fra_registry.c [new file with mode: 0644]
frsh_api/frsh_contract.c
frsh_api/frsh_core.c
resources/cpu_aquosa/lib/aqcpu_fra.c
resources/cpu_aquosa/lib/aqcpu_res.h
resources/dummy/fra_dummy.c
resources/dummy/res_dummy.h
resources/item/fra_item.c
resources/item/item.h

index 8f87c12a3623bb7ad9678df7537feb244eb6a253..33c7395bbbabfa718c8089009f5c12de002ef215 100644 (file)
@@ -1,5 +1,5 @@
 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
index 30dc4d13aba45313b3b407ac69a88aa82dbed0ff..6272cf286a4f7ca7ae6bd80b99a4331dc651f7c7 100644 (file)
@@ -221,44 +221,6 @@ err:
        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.
index 09e4362254896c2dfffc3883acf66e930bd9fb02..a1fa764428fae4b9b9ca2f34af1fa6275e76bd81 100644 (file)
@@ -110,16 +110,24 @@ struct fres_allocator {
         */
        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);
 
diff --git a/fres/resalloc/fra_registry.c b/fres/resalloc/fra_registry.c
new file mode 100644 (file)
index 0000000..58b0405
--- /dev/null
@@ -0,0 +1,198 @@
+/**
+ * @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(&registry);
+}
+
+/** 
+ * 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(&registry, &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(&registry, 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(&registry, &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;
+}
index 742225ed940262c89b7b914a200e0b8e3c2d5921..c24d0a4e63d85d06cbc4d21f0d29638c68f5f004 100644 (file)
@@ -163,6 +163,16 @@ int frsh_contract_negotiate
        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);
index 7bf578e02d4216d6fd12d6942b6f7f499a7032d8..b771de390e0fa68b1fcd1b30d33af62da3a8efb9 100644 (file)
@@ -1,6 +1,7 @@
 #include <frsh_core.h>
 #include <fcb.h>
 #include <forb.h>
+#include <fra_generic.h>
 #include "frsh_forb.h"
 #include <frsh_resources.h>
 
@@ -48,15 +49,16 @@ int frsh_init()
        /* 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
 
@@ -66,8 +68,7 @@ int frsh_init()
 #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 */
index cdc5c03d27f4d9387cc8b4f6a0b1ea2f0efd0219..1f15fb52e406d352b6f77ec4101f885ad51c2586 100644 (file)
@@ -185,7 +185,7 @@ static inline void aqcpu_cleanup_wrapper() {
  *  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;
@@ -195,7 +195,7 @@ int aqcpu_fra_init(forb_orb orb, fres_contract_broker fcb, forb_executor_t *exec
                return -1;
        }
        
-       if ((rv = fra_register(orb, fcb, executor, &aqcpu_allocator))) {
+       if ((rv = fra_register(&aqcpu_allocator))) {
                qres_cleanup();
                return rv;
        }
index b686c3b985092594c5a58a5cf811b1102ebf537d..cc251dfbea765609b5f851d47944a888cd7c6890 100644 (file)
@@ -5,7 +5,7 @@
 #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 */
 
index d47cc24d6b23fe8aaecdceacad2b4984b9c04060..ba7d0f2059d8e1f36ba6c86add0a4aee9ebd9cc6 100644 (file)
@@ -67,8 +67,8 @@ static struct fres_allocator dummy_allocator = {
        .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);
 }
index 708b14b801a27500ec7ff1da912e04a654ccd5f7..844204bfd34006e5a840ec1798dc1eaf354c3cc9 100644 (file)
@@ -10,7 +10,7 @@
 #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. */
index 4250dffb6b1d61cb61f4e8a44455d2d864c680e9..72b542b54bea804dea838639342300d63e509467 100644 (file)
@@ -3,6 +3,7 @@
 #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"};
@@ -48,10 +49,18 @@ static int change_vres(fres_vres_t *vres, void *priv)
        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,
@@ -59,19 +68,14 @@ static struct fres_allocator item_allocator = {
        .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);
 }
 
 /** 
index 26c2aea4449003105a13aa14e24710bcbdb48513..bc32400dcc3d26398d3f770d7d661a6e3c92bc87 100644 (file)
@@ -8,7 +8,7 @@
 #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. */