--- /dev/null
+/**
+ * @file frsh_power.c
+ * @author Michael Trimarchi <trimarchimichael@yahoo.it>
+ * Dario Faggioli <faggioli@gandalf.sssup.it>
+ *
+ * @brief FRSH core thread related functions not implamented in managers..
+ *
+ *
+ */
+
+#include <string.h>
+
+#include <fres_contract.h>
+#include <fres_contract_idl.h>
+#include <fres_blocks.h>
+#include <fcb.h>
+#include <fra_generic.h>
+#include "frsh_forb.h"
+#include "fra_acpi_cpu.h"
+
+#include <frsh.h>
+
+static inline int __is_a_valid_power(level)
+{
+ if (level >=0 && level < 3 )
+ return 1;
+
+ return 0;
+}
+
+int frsh_contract_set_min_expiration(frsh_contract_t *contract,
+ frsh_rel_time_t min_expiration)
+{
+ return FRSH_ERR_NOT_IMPLEMENTED;
+}
+
+int frsh_contract_set_min_budget_pow
+ (frsh_contract_t *contract,
+ frsh_power_level_t power_level,
+ const frsh_rel_time_t *pow_min_budget)
+{
+ fres_block_power_management *b;
+ int ret;
+
+ if (!contract || !*contract ||
+ !pow_min_budget)
+ return FRSH_ERR_BAD_ARGUMENT;
+
+ b = fres_contract_get_power_management(*contract);
+ if (!b) {
+ b = malloc(sizeof(*b));
+ if (!b) return ENOMEM;
+ }
+ b->min_budget[power_level] = *pow_min_budget;
+
+ fres_contract_del_power_management(*contract);
+ ret = fres_contract_add_power_management(*contract, b);
+ if (ret) {
+ free(b);
+ return errno;
+ }
+
+ return FRSH_NO_ERROR;
+}
+
+int frsh_contract_get_min_budget_pow
+ (const frsh_contract_t *contract,
+ frsh_power_level_t power_level,
+ frsh_rel_time_t *pow_min_budget)
+{
+ fres_block_power_management *b;
+
+ if (!contract || !*contract ||
+ !__is_a_valid_power(power_level))
+ return FRSH_ERR_BAD_ARGUMENT;
+
+ b = fres_contract_get_power_management(*contract);
+ if (!b)
+ return FRSH_ERR_BAD_ARGUMENT;
+
+ *pow_min_budget = b->min_budget[power_level];
+
+ return FRSH_NO_ERROR;
+}
+
+int frsh_contract_set_max_budget_pow
+ (frsh_contract_t *contract,
+ frsh_power_level_t power_level,
+ const frsh_rel_time_t *pow_max_budget)
+{
+ fres_block_power_management *b;
+ int ret;
+
+ if (!contract || !*contract ||
+ !pow_max_budget || !__is_a_valid_power(power_level))
+ return FRSH_ERR_BAD_ARGUMENT;
+
+ b = fres_contract_get_power_management(*contract);
+ if (!b) {
+ b = malloc(sizeof(*b));
+ if (!b) return ENOMEM;
+ }
+ b->max_budget[power_level] = *pow_max_budget;
+
+ fres_contract_del_power_management(*contract);
+ ret = fres_contract_add_power_management(*contract, b);
+ if (ret) {
+ free(b);
+ return errno;
+ }
+
+ return FRSH_NO_ERROR;
+}
+
+int frsh_contract_get_max_budget_pow(const frsh_contract_t *contract,
+ frsh_power_level_t power_level,
+ frsh_rel_time_t *pow_max_budget)
+{
+ fres_block_power_management *b;
+
+ if (!contract || !*contract ||
+ !__is_a_valid_power(power_level)) {
+ return FRSH_ERR_BAD_ARGUMENT;
+ }
+
+ b = fres_contract_get_power_management(*contract);
+ if (!b)
+ return FRSH_ERR_BAD_ARGUMENT;
+
+ *pow_max_budget = b->max_budget[power_level];
+
+ return FRSH_NO_ERROR;
+}
+
+int frsh_contract_set_utilization_pow
+ (frsh_contract_t *contract,
+ frsh_power_level_t power_level,
+ const frsh_rel_time_t *budget,
+ const frsh_rel_time_t *period,
+ const frsh_rel_time_t *deadline)
+{
+ return FRSH_ERR_NOT_IMPLEMENTED;
+}
+
+int frsh_contract_get_utilization_pow
+ (const frsh_contract_t *contract,
+ frsh_power_level_t power_level,
+ frsh_rel_time_t *budget,
+ frsh_rel_time_t *period,
+ frsh_rel_time_t *deadline)
+{
+ return FRSH_ERR_NOT_IMPLEMENTED;;
+}
+
+int frsh_resource_set_power_level
+ (frsh_resource_type_t resource_type,
+ frsh_resource_id_t resource_id,
+ frsh_power_level_t power_level)
+{
+ int ret;
+
+ switch(resource_type)
+ {
+ case FRSH_RT_PROCESSOR:
+ {
+ ret = fra_CPU_frequency_init(resource_id);
+ if (ret) goto err;
+
+ ret = fra_CPU_set_frequency(resource_id, power_level);
+ if (ret) goto err;
+
+ /**
+ * @TODO:
+ * if (i budget sono effettivamente diversi)
+ * rinegozia i contratti coi nuovi valori
+ **/
+
+ break;
+ }
+ case FRSH_RT_DISK:
+ return FRSH_ERR_NOT_IMPLEMENTED;
+ default:
+ return FRSH_ERR_INTERNAL_ERROR;
+ }
+
+ return FRSH_NO_ERROR;
+err:
+ return FRSH_ERR_INTERNAL_ERROR;
+}
+
+int frsh_resource_get_power_level
+ (frsh_resource_type_t resource_type,
+ frsh_resource_id_t resource_id,
+ frsh_power_level_t *power_level)
+{
+ int ret;
+
+ switch(resource_type)
+ {
+ case FRSH_RT_PROCESSOR:
+ {
+ ret = fra_CPU_get_level(resource_id, power_level);
+ if (ret) goto err;
+
+ break;
+ }
+ case FRSH_RT_DISK:
+ return FRSH_ERR_NOT_IMPLEMENTED;
+ default:
+ return FRSH_ERR_INTERNAL_ERROR;
+ }
+
+ return FRSH_NO_ERROR;
+err:
+ return FRSH_ERR_INTERNAL_ERROR;
+}
+
+int frsh_resource_get_num_power_levels
+ (frsh_resource_type_t resource_type,
+ frsh_resource_id_t resource_id,
+ frsh_power_level_t *num_power_levels)
+{
+ /**
+ * @FIXME:
+ * This looks tremendous... But the number '3' is hardcoded
+ * whereever in the headers as the number of power level, so...
+ */
+ return 3;
+}
+
+int frsh_battery_get_expiration(frsh_abs_time_t *expiration)
+{
+ return fra_CPU_battery_expiration(expiration);
+}
+