]> rtime.felk.cvut.cz Git - frescor/frsh.git/commitdiff
Additional FRA functionality implemented by virtual functions
authorMichal Sojka <sojkam1@fel.cvut.cz>
Sun, 10 May 2009 09:42:51 +0000 (11:42 +0200)
committerMichal Sojka <sojkam1@fel.cvut.cz>
Sun, 10 May 2009 09:42:51 +0000 (11:42 +0200)
The new virtual functions are:
- (un)bind_thread
- vres_get_XXX_usage
- support for feedback module

In d9964709b8f6fe7ebf97535daaf1a3c52f519f89, these functions were called
from switch statements in FRSH API and it was not possible to compile the
framework without DISK support (there were missing #ifdefs).

fres/resalloc/fra_generic.h
frsh_api/frsh_feedback.c
frsh_api/frsh_thread.c
frsh_api/frsh_vres.c
resources/cpu_aquosa/lib/aqcpu_fra.c
resources/cpu_aquosa/lib/aqcpu_res.h
resources/disk_bfq/lib/diskbfq_fra.c

index ac5c677864571642b9527324e780da3b54dfd941..10a500febb931f196d3efc374d9dfb015db8f14c 100644 (file)
@@ -181,6 +181,21 @@ struct fres_allocator {
        int (*apply_vres_changes)(fres_vres_t *vreses[], unsigned length, void *priv);
        /*@}*/
 
+       /** @name Feedback module support */
+       /*@{*/
+       int (*set_spare_bandwidth)(fres_vres_t *vres);
+       int (*get_desired_budget)(fres_vres_t *vres, frsh_rel_time_t *p_budget_out);
+       int (*set_desired_budget)(fres_vres_t *vres_id, frsh_rel_time_t *p_budget_in);
+       int (*get_actual_budget)(fres_vres_t *vres_id, frsh_rel_time_t *budget);
+       /*@}*/
+
+       int (*bind_thread)(fres_vres_t *vres, fosa_thread_id_t thread);
+       int (*unbind_thread)(fosa_thread_id_t thread);
+
+       int (*vres_get_job_usage)(const fres_vres_t *vres, frsh_rel_time_t *spent);
+       int (*vres_get_remaining_budget)(const fres_vres_t *vres, frsh_rel_time_t *budget);
+       int (*vres_get_usage)(const fres_vres_t *vres, frsh_rel_time_t *spent);
+
        void *priv;             /**< Pointer to allocator's private data */
 
        /**
index adfe2c153856e8ddce117e182a9dae371c70757d..86bfb44f3410ac43ac8f5e71fea5dfb76bd45eaa 100644 (file)
@@ -79,7 +79,6 @@ int frsh_feedback_set_spare
   (const frsh_contract_t *spare_contract)
 {
        int ret = 0;
-       fres_block_resource *r;
        frsh_vres_id_t spare_vres;
 
        if (!spare_contract || !*spare_contract)
@@ -88,24 +87,11 @@ int frsh_feedback_set_spare
        ret = frsh_contract_negotiate(spare_contract, &spare_vres);
        if (ret) return ret;
 
-       r = fres_contract_get_resource(*spare_contract);
-       switch(r->resource_type)
-       {
-               case FRSH_RT_PROCESSOR:
-               {
-                       ret = fra_CPU_set_spare_bandwidth(spare_vres);
-                       break;
-               }
-               case FRSH_RT_DISK:
-               {
-                       ret = fra_DISK_set_spare_bandwidth(spare_vres);
-                       break;
-               }
-               default:
-               {
-                       ret = FRSH_ERR_INTERNAL_ERROR;
-                       break;
-               }
+
+       if (spare_vres->allocator->set_spare_bandwidth) {
+               ret = spare_vres->allocator->set_spare_bandwidth(spare_vres);
+       } else {
+               ret = FRSH_ERR_NOT_IMPLEMENTED;
        }
 
        return ret;
@@ -115,89 +101,32 @@ int frsh_feedback_get_desired_budget
   (frsh_vres_id_t vres_id,
    frsh_rel_time_t *p_budget_out)
 {
-       struct fres_contract *contract = vres_id->perceived;
-       fres_block_resource *r = fres_contract_get_resource(contract);
-       int ret;
-
-       switch(r->resource_type)
-       {
-               case FRSH_RT_PROCESSOR:
-               {
-                       ret = fra_CPU_get_desired_budget(vres_id, p_budget_out);
-                       break;
-               }
-               case FRSH_RT_DISK:
-               {
-                       ret = fra_DISK_get_desired_budget(vres_id, p_budget_out);
-                       break;
-               }
-               default:
-                       goto err;
+       if (vres_id->allocator->get_desired_budget) {
+               return vres_id->allocator->get_desired_budget(vres_id, p_budget_out);
+       } else {
+               return FRSH_ERR_NOT_IMPLEMENTED;
        }
-       if (ret) goto err;
-
-       return FRSH_NO_ERROR;
-err:
-       return FRSH_ERR_INTERNAL_ERROR;
 }
 
 int frsh_feedback_set_desired_budget
   (frsh_vres_id_t vres_id,
    frsh_rel_time_t *p_budget_in)
 {
-       struct fres_contract *contract = vres_id->perceived;
-       fres_block_resource *r = fres_contract_get_resource(contract);
-       int ret;
-
-       switch(r->resource_type)
-       {
-               case FRSH_RT_PROCESSOR:
-               {
-                       ret = fra_CPU_set_desired_budget(vres_id, p_budget_in);
-                       break;
-               }
-               case FRSH_RT_DISK:
-               {
-                       ret = fra_DISK_set_desired_budget(vres_id, p_budget_in);
-                       break;
-               }
-               default:
-                       goto err;
+       if (vres_id->allocator->set_desired_budget) {
+               return vres_id->allocator->set_desired_budget(vres_id, p_budget_in);
+       } else {
+               return FRSH_ERR_NOT_IMPLEMENTED;
        }
-       if (ret) goto err;
-
-       return FRSH_NO_ERROR;
-err:
-       return FRSH_ERR_INTERNAL_ERROR;
 }
 
 int frsh_feedback_get_actual_budget
   (frsh_vres_id_t vres_id,
    frsh_rel_time_t *budget)
 {
-       struct fres_contract *contract = vres_id->perceived;
-       fres_block_resource *r = fres_contract_get_resource(contract);
-       int ret;
-
-       switch(r->resource_type)
-       {
-               case FRSH_RT_PROCESSOR:
-               {
-                       ret = fra_CPU_get_actual_budget(vres_id, budget);
-                       break;
-               }
-               case FRSH_RT_DISK:
-               {
-                       ret = fra_DISK_get_actual_budget(vres_id, budget);
-                       break;
-               }
-               default:
-                       goto err;
+       if (vres_id->allocator->get_actual_budget) {
+               return vres_id->allocator->get_actual_budget(vres_id, budget);
+       } else {
+               return FRSH_ERR_NOT_IMPLEMENTED;
        }
-       if (ret) goto err;
-
-       return FRSH_NO_ERROR;
-err:
-       return FRSH_ERR_INTERNAL_ERROR;
 }
 
index d5c89fb01cdcc4828d24ba400a68e5f43623eec6..5fa687c38e2ea753d963901ae5db6fc977187dcd 100644 (file)
@@ -44,33 +44,21 @@ int frsh_thread_bind
   (const frsh_vres_id_t vres,
    const frsh_thread_id_t thread)
 {
-       struct fres_contract *contract = vres->perceived;
-       fres_block_resource *r = fres_contract_get_resource(contract);
        int ret;
-
-       ret = fra_insert_thread_vres(&thread, r->resource_type, vres);
+       ret = fra_insert_thread_vres(&thread, vres->allocator->res_type, vres);
        if (ret) goto err;
-       switch(r->resource_type)
-       {
-               case FRSH_RT_PROCESSOR:
-               {
-                       ret = fra_CPU_bind_thread(vres, thread);
-                       break;
-               }
-               case FRSH_RT_DISK:
-               {
-                       ret = fra_DISK_bind_thread(vres, thread);
-                       break;
-               }
-               default:
-                       goto err_delete;
+       
+       if (vres->allocator->bind_thread) {
+               ret = vres->allocator->bind_thread(vres, thread);
+       } else {
+               ret = FRSH_ERR_NOT_IMPLEMENTED;
        }
        if (ret) goto err_delete;
 
        return FRSH_NO_ERROR;
 
 err_delete:
-       fra_delete_thread_vres(&thread, r->resource_type);
+       fra_delete_thread_vres(&thread, vres->allocator->res_type);
 err:
        return FRSH_ERR_INTERNAL_ERROR;
 }
@@ -93,31 +81,33 @@ err:
 int frsh_thread_unbind(const frsh_thread_id_t thread)
 {
        fres_vres_t *vres;
-       struct fres_contract *contract;
-       fres_block_resource *r;
        int ret;
 
        /* Unbound from FRSH_RT_PROCESSOR resource (if any) */
        vres = fra_get_vres_thread_vres(&thread, FRSH_RT_PROCESSOR);
        if (vres) {
-               contract = vres->perceived;
-               r = fres_contract_get_resource(contract);
-               ret = fra_CPU_unbind_thread(thread);
+               if (vres->allocator->unbind_thread) {
+                       ret = vres->allocator->unbind_thread(thread);
+               } else {
+                       ret = FRSH_ERR_NOT_IMPLEMENTED;
+               }
                if (ret) goto err;
 
-               ret = fra_delete_thread_vres(&thread, FRSH_RT_PROCESSOR);
+               ret = fra_delete_thread_vres(&thread, vres->allocator->res_type);
                if (ret) goto err;
        }
 
        /* Unbound from FRSH_RT_DISK resource (if any) */
        vres = fra_get_vres_thread_vres(&thread, FRSH_RT_DISK);
        if (vres) {
-               contract = vres->perceived;
-               r = fres_contract_get_resource(contract);
-               ret = fra_DISK_unbind_thread(thread);
+               if (vres->allocator->unbind_thread) {
+                       ret = vres->allocator->unbind_thread(thread);
+               } else {
+                       ret = FRSH_ERR_NOT_IMPLEMENTED;
+               }
                if (ret) goto err;
 
-               ret = fra_delete_thread_vres(&thread, FRSH_RT_DISK);
+               ret = fra_delete_thread_vres(&thread, vres->allocator->res_type);
                if (ret) goto err;
        }
 
index aa4e229bf306ac162f292419b39e8ef9748de1a0..0e56d23b0de90c126d897b75cec98a5141384d28 100644 (file)
@@ -160,89 +160,41 @@ int frsh_vres_get_usage
   (const frsh_vres_id_t vres,
    frsh_rel_time_t *spent)
 {
-        struct fres_contract *contract = vres->perceived;
-        fres_block_resource *r = fres_contract_get_resource(contract);
-       int ret;
-
-       switch(r->resource_type)
-       {
-               case FRSH_RT_PROCESSOR:
-               {
-                        ret = fra_CPU_get_usage(vres, spent);
-                       break;
-               }
-               case FRSH_RT_DISK:
-               {
-                       ret = fra_DISK_get_usage(vres, spent);
-                       break;
-               }
-               default:
-                       goto err;
+       if (!vres || !spent) {
+               return FRSH_ERR_BAD_ARGUMENT;
+       }
+       if (vres->allocator->vres_get_usage) {
+               return vres->allocator->vres_get_usage(vres, spent);
+       } else {
+               return FRSH_ERR_NOT_IMPLEMENTED;
        }
-       if (ret) goto err;
-
-       return FRSH_NO_ERROR;
-err:
-       return FRSH_ERR_INTERNAL_ERROR;
 }
 
 int frsh_vres_get_job_usage
   (const frsh_vres_id_t vres,
    frsh_rel_time_t *spent)
 {
-       struct fres_contract *contract = vres->perceived;
-       fres_block_resource *r = fres_contract_get_resource(contract);
-       int ret;
-
-       switch(r->resource_type)
-       {
-               case FRSH_RT_PROCESSOR:
-               {
-                        ret = fra_CPU_get_job_usage(vres, spent);
-                       break;
-               }
-               case FRSH_RT_DISK:
-               {
-                       ret = fra_DISK_get_job_usage(vres, spent);
-                       break;
-               }
-               default:
-                       goto err;
+       if (!vres || !spent) {
+               return FRSH_ERR_BAD_ARGUMENT;
+       }
+       if (vres->allocator->vres_get_job_usage) {
+               return vres->allocator->vres_get_job_usage(vres, spent);
+       } else {
+               return FRSH_ERR_NOT_IMPLEMENTED;
        }
-       if (ret) goto err;
-
-       return FRSH_NO_ERROR;
-err:
-       return FRSH_ERR_INTERNAL_ERROR;
 }
 
 int frsh_vres_get_remaining_budget
   (const frsh_vres_id_t vres,
    frsh_rel_time_t *budget)
 {
-        struct fres_contract *contract = vres->perceived;
-        fres_block_resource *r = fres_contract_get_resource(contract);
-       int ret;
-
-       switch(r->resource_type)
-       {
-               case FRSH_RT_PROCESSOR:
-               {
-                        ret = fra_CPU_get_remaining_budget(vres, budget);
-                       break;
-               }
-               case FRSH_RT_DISK:
-               {
-                       ret = fra_DISK_get_remaining_budget(vres, budget);
-                       break;
-               }
-               default:
-                       goto err;
+       if (!vres || !budget) {
+               return FRSH_ERR_BAD_ARGUMENT;
+       }
+       if (vres->allocator->vres_get_remaining_budget) {
+               return vres->allocator->vres_get_remaining_budget(vres, budget);
+       } else {
+               return FRSH_ERR_NOT_IMPLEMENTED;
        }
-       if (ret) goto err;
-
-       return FRSH_NO_ERROR;
-err:
-       return FRSH_ERR_INTERNAL_ERROR;
 }
 
index c9acd50f8d4c70561d4eec0dbae1c5af1fb2867a..0a9b82cfeaa4249e3ddffbca4ecc091190c09248 100644 (file)
@@ -139,6 +139,7 @@ static int aqcpu_cancel_vres(fres_vres_t *vres, void *priv)
  * possible.
  *
  */
+static
 int aqcpu_change_vres(fres_vres_t *vres, void *priv)
 {
        aqcpu_params_t cpu_params;
@@ -163,15 +164,6 @@ int aqcpu_change_vres(fres_vres_t *vres, void *priv)
        return 0;
 }
 
-static struct fres_allocator aqcpu_allocator = {
-       .res_type = FRSH_RT_PROCESSOR,
-       .res_id = 0,  /* CPU ID 0 */
-       .create_vres = aqcpu_create_vres,
-       .cancel_vres = aqcpu_cancel_vres,
-       .change_vres = aqcpu_change_vres,
-       .priv = NULL
-};
-
 /*
  * installed as an exit handler (with 'atexit()') by the initialization
  * code... For now it only calls the cleanup function of the AQuoSA
@@ -181,45 +173,7 @@ static inline void aqcpu_cleanup_wrapper() {
        qres_cleanup();
 }
 
-/*
- * aqcpu_fra_init(), initialize FRSH for the calling process
- *
- * Must be called before starting using the framework.
- * No FRSH call will be successful if this routine is not invoked
- *
- * Note that no BACKGROUND is created and negotiated and the caller thread
- * is bound to no BACKGROUND vres, since no way is provided in order of
- * specifying the contract label and get back the vres id!
- *
- * Note also that, since in this implementation the threads/processes with
- * backgound contracts are left into the default Linux scheduler hands' and
- * not attached to any AQuoSA server, while we're violating what D-AC2v1
- * (pag. 14) says, we achieve exactly the same behaviour!!
- */
-int aqcpu_fra_init(void)
-{
-       qos_rv qrv;
-       int rv;
-
-       if ((qrv = qres_init()) != QOS_OK) {
-               return -1;
-       }
-
-       if ((rv = fra_register(&aqcpu_allocator))) {
-               qres_cleanup();
-               return rv;
-       }
-       
-       /* install the cleanup function of th AQuoSA framework as an exit
-        * handler function (quite futile but, for now, it's sufficent) */
-       if (atexit(aqcpu_cleanup_wrapper))
-               return(FRSH_ERR_INTERNAL_ERROR);
-
-       aqcpu_initialized = 1;
-
-       return 0;
-}
-
+static
 int aqcpu_fra_exit()
 {
        qos_rv rv;
@@ -228,8 +182,9 @@ int aqcpu_fra_exit()
        return qos_rv_int(rv);
 }
 
+static
 int fra_CPU_bind_thread
-  (const fres_vres_t *vres,
+  (fres_vres_t *vres,
    const fosa_thread_id_t thread)
 {
        qos_rv  qrv;
@@ -244,6 +199,7 @@ err:
        return -1;
 }
 
+static
 int fra_CPU_unbind_thread(const fosa_thread_id_t thread)
 {
        qos_rv  qrv;
@@ -261,6 +217,7 @@ err:
        return -1;
 }
 
+static
 int fra_CPU_get_usage
   (const fres_vres_t *vres,
    fosa_rel_time_t *spent)
@@ -280,6 +237,7 @@ int fra_CPU_get_usage
        return 0;
 }
 
+static
 int fra_CPU_get_job_usage
   (const fres_vres_t *vres,
    fosa_rel_time_t *spent)
@@ -302,6 +260,7 @@ int fra_CPU_get_job_usage
        return 0;
 }
 
+static
 int fra_CPU_get_remaining_budget
   (const fres_vres_t *vres,
    fosa_rel_time_t *budget)
@@ -321,6 +280,7 @@ int fra_CPU_get_remaining_budget
        return 0;
 }
 
+static
 int fra_CPU_set_spare_bandwidth(fres_vres_t *vres)
 {
        qres_sid_t fake_sid = (qres_sid_t) -1;
@@ -344,6 +304,7 @@ int fra_CPU_set_spare_bandwidth(fres_vres_t *vres)
        return 0;
 }
 
+static
 int fra_CPU_get_desired_budget
   (fres_vres_t *vres,
    frsh_rel_time_t *p_budget_out)
@@ -363,6 +324,7 @@ int fra_CPU_get_desired_budget
        return 0;
 }
 
+static
 int fra_CPU_set_desired_budget
   (fres_vres_t *vres,
    fosa_rel_time_t *p_budget_in)
@@ -385,6 +347,7 @@ int fra_CPU_set_desired_budget
        return 0;
 }
 
+static
 int fra_CPU_get_actual_budget
   (fres_vres_t *vres,
    fosa_rel_time_t *budget)
@@ -404,3 +367,63 @@ int fra_CPU_get_actual_budget
        return 0;
 }
 
+static struct fres_allocator aqcpu_allocator = {
+       .res_type = FRSH_RT_PROCESSOR,
+       .res_id = 0,  /* CPU ID 0 */
+       .create_vres = aqcpu_create_vres,
+       .cancel_vres = aqcpu_cancel_vres,
+       .change_vres = aqcpu_change_vres,
+
+       .bind_thread = fra_CPU_bind_thread,
+       .unbind_thread = fra_CPU_unbind_thread,
+
+       .vres_get_usage = fra_CPU_get_usage,
+       .vres_get_job_usage = fra_CPU_get_job_usage,
+       .vres_get_remaining_budget = fra_CPU_get_remaining_budget,
+
+       .set_spare_bandwidth = fra_CPU_set_spare_bandwidth,
+       .get_desired_budget = fra_CPU_get_desired_budget,
+       .set_desired_budget = fra_CPU_set_desired_budget,
+       .get_actual_budget = fra_CPU_get_actual_budget,
+       
+       .priv = NULL
+};
+
+/*
+ * aqcpu_fra_init(), initialize FRSH for the calling process
+ *
+ * Must be called before starting using the framework.
+ * No FRSH call will be successful if this routine is not invoked
+ *
+ * Note that no BACKGROUND is created and negotiated and the caller thread
+ * is bound to no BACKGROUND vres, since no way is provided in order of
+ * specifying the contract label and get back the vres id!
+ *
+ * Note also that, since in this implementation the threads/processes with
+ * backgound contracts are left into the default Linux scheduler hands' and
+ * not attached to any AQuoSA server, while we're violating what D-AC2v1
+ * (pag. 14) says, we achieve exactly the same behaviour!!
+ */
+int aqcpu_fra_init(void)
+{
+       qos_rv qrv;
+       int rv;
+
+       if ((qrv = qres_init()) != QOS_OK) {
+               return -1;
+       }
+
+       if ((rv = fra_register(&aqcpu_allocator))) {
+               qres_cleanup();
+               return rv;
+       }
+       
+       /* install the cleanup function of th AQuoSA framework as an exit
+        * handler function (quite futile but, for now, it's sufficent) */
+       if (atexit(aqcpu_cleanup_wrapper))
+               return(FRSH_ERR_INTERNAL_ERROR);
+
+       aqcpu_initialized = 1;
+
+       return 0;
+}
index 078d88a84c36c651bd698142c590784f0f2250a4..709bc637343aaea209dde87e8edad3466596e810 100644 (file)
 
 int aqcpu_fra_init(void);
 
-int fra_CPU_bind_thread(fres_vres_t *vres, fosa_thread_id_t thread);
-int fra_CPU_unbind_thread(fosa_thread_id_t thread);
-
-int fra_CPU_get_usage(const fres_vres_t *vres,
-                     fosa_rel_time_t *spent);
-int fra_CPU_get_job_usage(const fres_vres_t *vres,
-                         fosa_rel_time_t *spent);
-int fra_CPU_get_remaining_budget(const fres_vres_t *vres,
-                                fosa_rel_time_t *budget);
-
-int fra_CPU_set_spare_bandwidth(fres_vres_t *vres);
-
-int fra_CPU_get_desired_budget(fres_vres_t *vres,
-                              frsh_rel_time_t *p_budget_out);
-int fra_CPU_set_desired_budget(fres_vres_t *vres,
-                              fosa_rel_time_t *p_budget_in);
-int fra_CPU_get_actual_budget(fres_vres_t *vres,
-                             fosa_rel_time_t *budget);
-
 #endif /* AQCPU_RES_H */
 
index 1fc8fd2db0c23d1f84dbd6b9e5b7ef4792664ef1..670f804730027e24700486c9089ec18aa2231745 100644 (file)
@@ -122,6 +122,7 @@ static int diskbfq_cancel_vres(fres_vres_t *vres, void *priv)
        return 0;
 }
 
+static
 int diskbfq_change_vres(fres_vres_t *vres, void *priv)
 {
        fres_block_disk_sched *disk_sched;
@@ -139,59 +140,14 @@ int diskbfq_change_vres(fres_vres_t *vres, void *priv)
        return 0;
 }
 
-static struct fres_allocator diskbfq_allocator = {
-       .res_type = FRSH_RT_DISK,
-       .res_id = 0,  /* DISK ID 0 */
-       .create_vres = diskbfq_create_vres,
-       .cancel_vres = diskbfq_cancel_vres,
-       .change_vres = diskbfq_change_vres,
-       .priv = NULL
-};
-
-/*
- * diskbfq_fra_init()
- *
- * initialize FRSH for the calling process
- *
- * Must be called before starting using the framework.
- * No FRSH call will be successful if this routine is not invoked
- *
- * Note that no BACKGROUND is created and negotiated and the caller thread
- * is bound to no BACKGROUND vres, since no way is provided in order of
- * specifying the contract label and get back the vres id!
- *
- * Note also that, since in this implementation the threads/processes with
- * backgound contracts are left into the default Linux scheduler hands' and
- * not attached to any AQuoSA server, while we're violating what D-AC2v1
- * (pag. 14) says, we achieve exactly the same behaviour!!
- *
- * possible return values:
- *  FRSH_NO_ERROR
- *  FRSH_ERR_ALREADY_INITIALIZED
- *  FRSH_ERR_INTERNAL_ERROR (something, different from the previous case, gone wrong)
- */
-int diskbfq_fra_init(void)
-{
-       if (diskbfq_is_initialized()) {
-               return -1;
-       }
-
-       fres_block_register_disk_sched();
-       if (fra_register(&diskbfq_allocator)) {
-               return -1;
-       }
-       
-       diskbfq_initialized = 1;
-       return 0;
-}
-
 int diskbfq_fra_exit()
 {
        return 0;
 }
 
+static
 int fra_DISK_bind_thread
-  (const fres_vres_t *vres,
+  (fres_vres_t *vres,
    const fosa_thread_id_t thread)
 {
        fres_block_basic *b;
@@ -216,6 +172,7 @@ err:
        return -1;
 }
 
+static
 int fra_DISK_unbind_thread(const fosa_thread_id_t thread)
 {
        int ret;
@@ -229,6 +186,7 @@ int fra_DISK_unbind_thread(const fosa_thread_id_t thread)
        return 0;
 }
 
+static
 int fra_DISK_get_usage
   (const fres_vres_t *vres,
    fosa_rel_time_t *spent)
@@ -236,6 +194,7 @@ int fra_DISK_get_usage
        return -1;
 }
 
+static
 int fra_DISK_get_job_usage
   (const fres_vres_t *vres,
    fosa_rel_time_t *spent)
@@ -243,6 +202,7 @@ int fra_DISK_get_job_usage
        return -1;
 }
 
+static
 int fra_DISK_get_remaining_budget
   (const fres_vres_t *vres,
    fosa_rel_time_t *budget)
@@ -250,12 +210,14 @@ int fra_DISK_get_remaining_budget
        return -1;
 }
 
+static
 int fra_DISK_set_spare_bandwidth
   (fres_vres_t *vres)
 {
        return -1;
 }
 
+static
 int fra_DISK_get_desired_budget
   (fres_vres_t *vres,
    frsh_rel_time_t *p_budget_out)
@@ -263,6 +225,7 @@ int fra_DISK_get_desired_budget
        return -1;
 }
 
+static
 int fra_DISK_set_desired_budget
   (fres_vres_t *vres,
    fosa_rel_time_t *p_budget_in)
@@ -270,6 +233,7 @@ int fra_DISK_set_desired_budget
        return -1;
 }
 
+static
 int fra_DISK_get_actual_budget
   (fres_vres_t *vres,
    fosa_rel_time_t *budget)
@@ -277,3 +241,62 @@ int fra_DISK_get_actual_budget
        return -1;
 }
 
+static struct fres_allocator diskbfq_allocator = {
+       .res_type = FRSH_RT_DISK,
+       .res_id = 0,  /* DISK ID 0 */
+       .create_vres = diskbfq_create_vres,
+       .cancel_vres = diskbfq_cancel_vres,
+       .change_vres = diskbfq_change_vres,
+
+       .bind_thread = fra_DISK_bind_thread,
+       .unbind_thread = fra_DISK_unbind_thread,
+
+       .vres_get_usage = fra_DISK_get_usage,
+       .vres_get_job_usage = fra_DISK_get_job_usage,
+       .vres_get_remaining_budget = fra_DISK_get_remaining_budget,
+
+       .set_spare_bandwidth = fra_DISK_set_spare_bandwidth,
+       .get_desired_budget = fra_DISK_get_desired_budget,
+       .set_desired_budget = fra_DISK_set_desired_budget,
+       .get_actual_budget = fra_DISK_get_actual_budget,
+
+       .priv = NULL
+};
+
+/*
+ * diskbfq_fra_init()
+ *
+ * initialize FRSH for the calling process
+ *
+ * Must be called before starting using the framework.
+ * No FRSH call will be successful if this routine is not invoked
+ *
+ * Note that no BACKGROUND is created and negotiated and the caller thread
+ * is bound to no BACKGROUND vres, since no way is provided in order of
+ * specifying the contract label and get back the vres id!
+ *
+ * Note also that, since in this implementation the threads/processes with
+ * backgound contracts are left into the default Linux scheduler hands' and
+ * not attached to any AQuoSA server, while we're violating what D-AC2v1
+ * (pag. 14) says, we achieve exactly the same behaviour!!
+ *
+ * possible return values:
+ *  FRSH_NO_ERROR
+ *  FRSH_ERR_ALREADY_INITIALIZED
+ *  FRSH_ERR_INTERNAL_ERROR (something, different from the previous case, gone wrong)
+ */
+int diskbfq_fra_init(void)
+{
+       if (diskbfq_is_initialized()) {
+               return -1;
+       }
+
+       fres_block_register_disk_sched();
+       if (fra_register(&diskbfq_allocator)) {
+               return -1;
+       }
+       
+       diskbfq_initialized = 1;
+       return 0;
+}
+