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 */
/**
(const frsh_contract_t *spare_contract)
{
int ret = 0;
- fres_block_resource *r;
frsh_vres_id_t spare_vres;
if (!spare_contract || !*spare_contract)
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;
(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;
}
(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;
}
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;
}
(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;
}
* possible.
*
*/
+static
int aqcpu_change_vres(fres_vres_t *vres, void *priv)
{
aqcpu_params_t cpu_params;
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
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;
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;
return -1;
}
+static
int fra_CPU_unbind_thread(const fosa_thread_id_t thread)
{
qos_rv qrv;
return -1;
}
+static
int fra_CPU_get_usage
(const fres_vres_t *vres,
fosa_rel_time_t *spent)
return 0;
}
+static
int fra_CPU_get_job_usage
(const fres_vres_t *vres,
fosa_rel_time_t *spent)
return 0;
}
+static
int fra_CPU_get_remaining_budget
(const fres_vres_t *vres,
fosa_rel_time_t *budget)
return 0;
}
+static
int fra_CPU_set_spare_bandwidth(fres_vres_t *vres)
{
qres_sid_t fake_sid = (qres_sid_t) -1;
return 0;
}
+static
int fra_CPU_get_desired_budget
(fres_vres_t *vres,
frsh_rel_time_t *p_budget_out)
return 0;
}
+static
int fra_CPU_set_desired_budget
(fres_vres_t *vres,
fosa_rel_time_t *p_budget_in)
return 0;
}
+static
int fra_CPU_get_actual_budget
(fres_vres_t *vres,
fosa_rel_time_t *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;
+}
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 */
return 0;
}
+static
int diskbfq_change_vres(fres_vres_t *vres, void *priv)
{
fres_block_disk_sched *disk_sched;
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;
return -1;
}
+static
int fra_DISK_unbind_thread(const fosa_thread_id_t thread)
{
int ret;
return 0;
}
+static
int fra_DISK_get_usage
(const fres_vres_t *vres,
fosa_rel_time_t *spent)
return -1;
}
+static
int fra_DISK_get_job_usage
(const fres_vres_t *vres,
fosa_rel_time_t *spent)
return -1;
}
+static
int fra_DISK_get_remaining_budget
(const fres_vres_t *vres,
fosa_rel_time_t *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)
return -1;
}
+static
int fra_DISK_set_desired_budget
(fres_vres_t *vres,
fosa_rel_time_t *p_budget_in)
return -1;
}
+static
int fra_DISK_get_actual_budget
(fres_vres_t *vres,
fosa_rel_time_t *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;
+}
+