#include <fra_generic.h>
#include "aquosa/qres_lib.h"
+#include "aquosa/qsup_lib.h"
+
#include "aqcpu_contract.h"
UL_LOG_CUST(ulogd_fra_aqcpu);
* 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 aqcpu_fra_init(void)
{
int rv;
if ((qrv = qres_init()) != QOS_OK) {
- errno = -EPERM;
return -1;
}
-
+
if ((rv = fra_register(&aqcpu_allocator))) {
qres_cleanup();
return rv;
rv = qres_cleanup();
return qos_rv_int(rv);
}
+
+int fra_CPU_bind_thread
+ (const fres_vres_t *vres,
+ const fosa_thread_id_t thread)
+{
+ qos_rv qrv;
+ qres_sid_t sid = *((qres_sid_t*)vres->priv);
+
+ if ((qrv = qres_attach_thread(sid, thread.linux_pid,
+ thread.linux_tid)) != QOS_OK)
+ goto err;
+
+ return 0;
+err:
+ return -1;
+}
+
+int fra_CPU_unbind_thread(const fosa_thread_id_t thread)
+{
+ qos_rv qrv;
+ qres_sid_t sid;
+
+ if (qres_get_sid(thread.linux_pid, thread.linux_tid, &sid) != QOS_OK)
+ goto err;
+
+ if ((qrv = qres_detach_thread(sid, thread.linux_pid,
+ thread.linux_tid)) != QOS_OK)
+ goto err;
+
+ return 0;
+err:
+ return -1;
+}
+
+int fra_CPU_get_usage
+ (const fres_vres_t *vres,
+ fosa_rel_time_t *spent)
+{
+ qres_sid_t sid = *((qres_sid_t*)vres->priv);
+ qres_time_t exec_budget;
+ qos_rv rv;
+
+ if (!spent)
+ return FRSH_ERR_BAD_ARGUMENT;
+
+ rv = qres_get_exec_time(sid, &exec_budget, NULL);
+ if (rv != QOS_OK) return EINVAL;
+
+ *spent = fosa_usec_to_rel_time(exec_budget);
+
+ return 0;
+}
+
+int fra_CPU_get_job_usage
+ (const fres_vres_t *vres,
+ fosa_rel_time_t *spent)
+{
+ qres_sid_t sid = *((qres_sid_t*)vres->priv);
+ qres_params_t q_params;
+ qres_time_t curr_budget;
+ qos_rv rv;
+
+ if (!spent)
+ return FRSH_ERR_BAD_ARGUMENT;
+
+ rv = qres_get_params(sid, &q_params);
+ if (rv != QOS_OK) return EINVAL;
+ rv = qres_get_curr_budget(sid, &curr_budget);
+ if (rv != QOS_OK) return EINVAL;
+
+ *spent = fosa_usec_to_rel_time(q_params.Q - curr_budget);
+
+ return 0;
+}
+
+int fra_CPU_get_remaining_budget
+ (const fres_vres_t *vres,
+ fosa_rel_time_t *budget)
+{
+ qres_sid_t sid = *((qres_sid_t*)vres->priv);
+ qres_time_t curr_budget;
+ qos_rv rv;
+
+ if (!budget)
+ return FRSH_ERR_BAD_ARGUMENT;
+
+ rv = qres_get_curr_budget(sid, &curr_budget);
+ if (rv != QOS_OK) return EINVAL;
+
+ *budget = fosa_usec_to_rel_time(curr_budget);
+
+ return 0;
+}
+
+int fra_CPU_set_spare_bandwidth(fres_vres_t *vres)
+{
+ qres_sid_t fake_sid = (qres_sid_t) -1;
+ aqcpu_params_t cpu_params;
+ qos_rv rv;
+
+ /* get aqcpu params from contract */
+ get_aqcpu_params(vres, &cpu_params);
+
+
+ /* reserve CPU bandwidth for feedback */
+ rv = qsup_reserve_spare(r2bw(cpu_params.Q, cpu_params.P));
+ if (rv != QOS_OK) return qos_rv_int(rv);
+
+ printf("Created AQCPU spare (period=%lld us, budget=%lld us)\n",
+ cpu_params.P, cpu_params.Q);
+ if ((vres->priv = malloc(sizeof(qres_sid_t)))) {
+ memcpy(vres->priv, &fake_sid, sizeof(qres_sid_t));
+ }
+
+ return 0;
+}
+
+int fra_CPU_get_desired_budget
+ (fres_vres_t *vres,
+ frsh_rel_time_t *p_budget_out)
+{
+ qres_sid_t sid = *((qres_sid_t*)vres->priv);
+ qres_params_t q_params;
+ qos_rv rv;
+
+ if (!p_budget_out)
+ return FRSH_ERR_BAD_ARGUMENT;
+
+ rv = qres_get_params(sid, &q_params);
+ if (rv != QOS_OK) return EINVAL;
+
+ *p_budget_out = fosa_usec_to_rel_time(q_params.Q);
+
+ return 0;
+}
+
+int fra_CPU_set_desired_budget
+ (fres_vres_t *vres,
+ fosa_rel_time_t *p_budget_in)
+{
+ qres_sid_t sid = *((qres_sid_t*)vres->priv);
+ qres_params_t q_params;
+ qos_rv rv;
+
+ if (!p_budget_in)
+ return FRSH_ERR_BAD_ARGUMENT;
+
+ rv = qres_get_params(sid, &q_params);
+ if (rv != QOS_OK) return EINVAL;
+
+ q_params.Q = fosa_rel_time_to_usec(*p_budget_in);
+
+ rv = qres_set_params(sid, &q_params);
+ if (rv != QOS_OK) return EINVAL;
+
+ return 0;
+}
+
+int fra_CPU_get_actual_budget
+ (fres_vres_t *vres,
+ fosa_rel_time_t *budget)
+{
+ qres_sid_t sid = *((qres_sid_t*)vres->priv);
+ qres_time_t appr_budget;
+ qos_rv rv;
+
+ if (!budget)
+ return FRSH_ERR_BAD_ARGUMENT;
+
+ rv = qres_get_appr_budget(sid, &appr_budget);
+ if (rv != QOS_OK) return EINVAL;
+
+ *budget = fosa_usec_to_rel_time(appr_budget);
+
+ return 0;
+}
+