id /* cust_item_key */,
fres_contract_id_cmp /* cust_cmp_fnc */);
+
+/**
+ * * Global "registry" of all bound threads in one application.
+ * */
+struct fres_threads_vres fres_threads_vres;
+
+GAVL_CUST_NODE_INT_IMP(fres_threads_vres_nolock /* cust_prefix */,
+ struct fres_threads_vres /* cust_root_t */,
+ struct fres_thread_vres /* cust_item_t */,
+ fosa_thread_id_t /* cust_key_t */,
+ threads /* cust_root_node */,
+ node /* cust_item_node */,
+ id /* cust_item_key */,
+ fres_thread_vres_cmp /* cust_cmp_fnc */);
+
+
/**
* Inserts vres to the global vres "registry".
*
{
return fres_vreses_find(id);
}
+
+static inline
+int fres_threads_vres_insert(struct fres_thread_vres *th)
+{
+ int ret;
+
+ fosa_mutex_lock(&fres_threads_vres.mutex);
+ ret = fres_threads_vres_nolock_insert(&fres_threads_vres, th);
+ fosa_mutex_unlock(&fres_threads_vres.mutex);
+
+ return ret;
+}
+
+static inline
+int fres_threads_vres_delete(struct fres_thread_vres *th)
+{
+ int ret;
+
+ fosa_mutex_lock(&fres_threads_vres.mutex);
+ ret = fres_threads_vres_nolock_delete(&fres_threads_vres, th);
+ fosa_mutex_unlock(&fres_threads_vres.mutex);
+
+ return ret;
+}
+
+static inline
+struct fres_thread_vres *fres_threads_vres_find(const fosa_thread_id_t *id)
+{
+ struct fres_thread_vres *ret;
+
+ fosa_mutex_lock(&fres_threads_vres.mutex);
+ ret = fres_threads_vres_nolock_find(&fres_threads_vres, id);
+ fosa_mutex_unlock(&fres_threads_vres.mutex);
+
+ return ret;
+}
+
+int fra_insert_thread_vres(const fosa_thread_id_t *id, fres_vres_t *vres)
+{
+ struct fres_thread_vres *th;
+
+ th = fres_threads_vres_find(id);
+ if (th) {
+ fosa_mutex_lock(&fres_threads_vres.mutex);
+ th->vres = vres;
+ fosa_mutex_unlock(&fres_threads_vres.mutex);
+
+ return 0;
+ }
+
+ th = fres_thread_vres_new(id, vres);
+ if (!th) return -1;
+
+ return fres_threads_vres_insert(th);
+}
+
+int fra_delete_thread_vres(const fosa_thread_id_t *id)
+{
+ struct fres_thread_vres *th;
+
+ th = fres_threads_vres_find(id);
+ if (!th) return -1;
+
+ fres_thread_vres_destroy(th);
+
+ return 0;
+}
+
+fres_thread_vres_t *fra_get_thread_vres(const fosa_thread_id_t *id)
+{
+ return fres_threads_vres_find(id);
+}
+
+fres_vres_t *fra_get_vres_thread_vres(const fosa_thread_id_t *id)
+{
+ fres_thread_vres_t *th_vres;
+
+ th_vres = fres_threads_vres_find(id);
+ if (!th_vres) return NULL;
+
+ return th_vres->vres;
+
+}
+
extern struct fres_vreses fres_vreses;
+/** Registry of all threads in an application that are bound to a VRES. */
+struct fres_threads_vres {
+ fosa_mutex_t mutex; /**< Mutex for manipulation with vreses tree. If all allocators are executed from one executor, locking can be avoided. */
+ gavl_cust_root_field_t threads; /**< Container of all virtual resources */
+};
+
+GAVL_CUST_NODE_INT_DEC(fres_threads_vres_nolock /* cust_prefix */,
+ struct fres_threads_vres /* cust_root_t */,
+ struct fres_thread_vres /* cust_item_t */,
+ fosa_thread_id_t /* cust_key_t */,
+ threads /* cust_root_node */,
+ node /* cust_item_node */,
+ id /* cust_item_key */,
+ fres_thread_vres_cmp /* cust_cmp_fnc */)
+
+extern struct fres_threads_vres fres_threads_vres;
+
+
/**
* Structure describing FRES allocator. It is used as a parameter to
* fra_register(), which registeres this allocator with contract
fres_vres_t *fra_get_vres(fres_contract_id_t *id);
+int fra_insert_thread_vres(const fosa_thread_id_t *id, fres_vres_t *vres);
+int fra_delete_thread_vres(const fosa_thread_id_t *id);
+fres_thread_vres_t *fra_get_thread_vres(const fosa_thread_id_t *id);
+fres_vres_t *fra_get_vres_thread_vres(const fosa_thread_id_t *id);
+
#endif
}
free(vres);
}
+
+fres_thread_vres_t *fres_thread_vres_new
+ (const fosa_thread_id_t *id,
+ fres_vres_t *vres)
+{
+ fres_thread_vres_t *th;
+
+ th = malloc(sizeof(*th));
+ if (!th) goto out;
+
+ memset(th, 0, sizeof(*th));
+ th->id = *id;
+ th->vres = vres;
+
+out:
+ return th;
+}
+
+void fres_thread_vres_destroy(fres_thread_vres_t *th_vres)
+{
+ if (!th_vres) return;
+
+ free(th_vres);
+}
+
#ifndef FRES_VRES_H
#define FRES_VRES_H
+#include <fosa.h>
+
#include <fres_contract_idl.h>
#include <ul_gavlcust.h>
typedef struct fres_vres {
/** Contracts IDs of this VRES. */
fres_contract_id_t id;
-
+
/**
* Stores actual allocation of the resource. During a mode
* change, the callbacks can compare this old allocation with
* field.
*/
struct fres_contract *new;
-
+
struct fres_allocator *allocator;
void *priv; /**< Resource allocator private data */
gavl_node_t node;
void fres_vres_destroy(fres_vres_t *vres);
+typedef struct fres_thread_vres {
+ fosa_thread_id_t id;
+ fres_vres_t *vres;
+
+ fosa_abs_time_t job_start_time;
+ fosa_abs_time_t job_cpu_time;
+
+ gavl_node_t node;
+} fres_thread_vres_t;
+
+static inline
+int fres_thread_vres_cmp(const fosa_thread_id_t *a, const fosa_thread_id_t *b)
+{
+ return fosa_thread_equal(*a, *b);
+}
+
+fres_thread_vres_t *fres_thread_vres_new
+ (const fosa_thread_id_t *id,
+ fres_vres_t *vres);
+
+void fres_thread_vres_destroy(fres_thread_vres_t *th_vres);
+
+
#endif
SUBDIRS = tests
shared_LIBRARIES = frsh
-frsh_SOURCES = frsh_contract.c frsh_distributed.c frsh_core.c frsh_error.c frsh_thread.c frsh_synchobj.c frsh_sharedobj.c
+frsh_SOURCES = frsh_contract.c frsh_vres.c frsh_distributed.c frsh_core.c frsh_error.c frsh_thread.c
include_HEADERS = frsh_opaque_types.h frsh_forb.h
frsh_LIBS = fna fcb_client forb contract fra ulut fosa $(allocator-libs-y)
return FRSH_ERR_NOT_IMPLEMENTED;
}
+int frsh_group_change_mode_sync
+ (const frsh_contracts_group_t *contracts_to_neg,
+ const frsh_contracts_group_t *contracts_to_reneg,
+ const frsh_vres_group_t *vres_to_reneg,
+ const frsh_vres_group_t *vres_to_cancel,
+ frsh_vres_group_t *new_vres)
+{
+ return FRSH_ERR_NOT_IMPLEMENTED;
+}
+
+int frsh_group_change_mode_async
+ (const frsh_contracts_group_t *contracts_to_neg,
+ const frsh_contracts_group_t *contracts_to_reneg,
+ const frsh_vres_group_t *vres_to_reneg,
+ const frsh_vres_group_t *vres_to_cancel,
+ const frsh_signal_t signal,
+ const frsh_signal_info_t signal_info,
+ frsh_group_id_t *group)
+{
+ return FRSH_ERR_NOT_IMPLEMENTED;
+}
+
/**
* @file frsh_core.c
* @author Michal Sojka <sojkam1@fel.cvut.cz>
+ * Dario Faggioli <faggioli@gandalf.sssup.it>
* @date Wed Feb 18 16:04:22 2009
*
* @brief Core of FRSH_FORB framework
return ret;
}
+bool frsh_config_is_admission_test_enabled()
+{
+ return true;
+}
+
frsh_contract_init(&contract);
frsh_contract_set_resource_and_label(&contract,
FRSH_RT_PROCESSOR,
- contract_label,
- NULL);
+ 0,
+ contract_label);
frsh_contract_set_basic_params(&contract,
&zero_msec,
&zero_msec,
rv = frsh_contract_negotiate(&contract, vres_id);
if (rv !=0) goto error;
- rv = fosa_thread_create(thread, attr, thread_code, thread_arg);
+ rv = fosa_thread_create(thread, attr, thread_code, (void*) thread_arg);
if (rv != 0) goto error;
return 0;
(const frsh_thread_id_t thread,
frsh_vres_id_t *vres_id)
{
- return FRSH_ERR_NOT_IMPLEMENTED;
+ if (!vres_id)
+ return FRSH_ERR_BAD_ARGUMENT;
+
+ *vres_id = fra_get_vres_thread_vres(&thread);
+
+ return vres_id ? 0 : EINVAL;
}
int frsh_service_thread_set_data
--- /dev/null
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* Copyright (C) 2006 - 2008 FRESCOR consortium partners: */
+/* */
+/* Universidad de Cantabria, SPAIN */
+/* University of York, UK */
+/* Scuola Superiore Sant'Anna, ITALY */
+/* Kaiserslautern University, GERMANY */
+/* Univ. Politécnica Valencia, SPAIN */
+/* Czech Technical University in Prague, CZECH REPUBLIC */
+/* ENEA SWEDEN */
+/* Thales Communication S.A. FRANCE */
+/* Visual Tools S.A. SPAIN */
+/* Rapita Systems Ltd UK */
+/* Evidence ITALY */
+/* */
+/* See http://www.frescor.org for a link to partners' websites */
+/* */
+/* FRESCOR project (FP6/2005/IST/5-034026) is funded */
+/* in part by the European Union Sixth Framework Programme */
+/* The European Union is not liable of any use that may be */
+/* made of this code. */
+/* */
+/* */
+/* This file is part of FRSH (FRescor ScHeduler) */
+/* */
+/* FRSH is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. FRSH is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with FRSH; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* As a special exception, including FRSH header files in a file, */
+/* instantiating FRSH generics or templates, or linking other files */
+/* with FRSH objects to produce an executable application, does not */
+/* by itself cause the resulting executable application to be covered */
+/* by the GNU General Public License. This exception does not */
+/* however invalidate any other reasons why the executable file might be */
+/* covered by the GNU Public License. */
+/**************************************************************************/
+
+/**
+ * @file frsh_vres.c
+ * @author Dario Faggioli <faggioli@gandalf.sssup.it>
+ * @date Wed Feb 20 14:53:22 2009
+ *
+ * @brief Core of FRSH_FORB framework
+ *
+ */
+
+
+#include <frsh_core.h>
+#include <fra_generic.h>
+#include "frsh_forb.h"
+#include <frsh_resources.h>
+
+int frsh_vres_get_priority
+ (frsh_vres_id_t vres_id,
+ int *priority)
+{
+ return FRSH_ERR_NOT_IMPLEMENTED;
+}
+
+int frsh_vres_get_contract
+ (const frsh_vres_id_t vres,
+ frsh_contract_t *contract)
+{
+ if (!vres) return EINVAL;
+
+ *contract = vres->perceived;
+
+ return 0;
+}
+
+int frsh_resource_get_vres_from_label
+ (const char *contract_label,
+ const frsh_resource_type_t resource_type,
+ const frsh_resource_id_t resource_id,
+ frsh_vres_id_t *vres)
+{
+ return FRSH_ERR_NOT_IMPLEMENTED;
+}
+
+int frsh_vres_get_renegotiation_status
+ (const frsh_vres_id_t vres,
+ frsh_renegotiation_status_t *renegotiation_status)
+{
+ return FRSH_ERR_NOT_IMPLEMENTED;
+}
+
+int frsh_group_get_status
+ (const frsh_group_id_t group,
+ frsh_renegotiation_status_t *status,
+ frsh_vres_group_t *new_vres)
+{
+ return FRSH_ERR_NOT_IMPLEMENTED;
+}
+
+int frsh_vres_get_budget_and_period
+ (const frsh_vres_id_t vres,
+ frsh_rel_time_t *budget,
+ frsh_rel_time_t *period)
+{
+ fres_block_basic *basic;
+
+ if (!vres) return EINVAL;
+
+ basic = fres_contract_get_basic(vres->perceived);
+
+ if (budget)
+ *budget = basic->budget;
+ if (period)
+ *period = basic->period;
+
+ return 0;
+}
+
#include <fosa.h>
#include <frsh_core_types.h>
#include <frsh_error.h>
+#include <frsh_time.h>
#include <fres_vres.h>
+#include <fra_generic.h>
/* AQuoSA files */
#include <aquosa/qres_lib.h>
*/
int frsh_thread_bind(const frsh_vres_id_t vres, const frsh_thread_id_t thread)
{
+ int ret;
qos_rv qrv;
qres_sid_t sid = *((qres_sid_t*)vres->priv);
+ fres_thread_vres_t *th;
/*if (!aqcpu_is_initialized) {
return(FRSH_ERR_NOT_INITIALIZED);
}*/
+ ret = fra_insert_thread_vres(&thread, vres);
+ if (ret) goto err;
+
if ((qrv = qres_attach_thread(sid, thread.linux_pid,
- thread.linux_tid)) != QOS_OK) {
- /* return qos_rv_int(qrv);*/
- return FRSH_ERR_INTERNAL_ERROR;
- }
+ thread.linux_tid)) != QOS_OK)
+ goto err_delete;
- return FRSH_NO_ERROR;
+ return FRSH_NO_ERROR;
+
+err_delete:
+ fra_delete_thread_vres(&thread);
+err:
+ return FRSH_ERR_INTERNAL_ERROR;
}
/*
*/
int frsh_thread_unbind(const frsh_thread_id_t thread)
{
+ int ret;
qos_rv qrv;
qres_sid_t sid;
- if (qres_get_sid(thread.linux_pid, thread.linux_tid, &sid) != QOS_OK){
- return -1;
- }
+ if (qres_get_sid(thread.linux_pid, thread.linux_tid, &sid) != QOS_OK)
+ goto err;
+
+ ret = fra_delete_thread_vres(&thread);
+ if (ret) goto err;
if ((qrv = qres_detach_thread(sid, thread.linux_pid,
- thread.linux_tid)) != QOS_OK) {
- /*return qos_rv_int(qrv);*/
- return FRSH_ERR_INTERNAL_ERROR;
- }
+ thread.linux_tid)) != QOS_OK)
+ goto err;
return FRSH_NO_ERROR;
+err:
+ return FRSH_ERR_INTERNAL_ERROR;
}
/**
return (wp.errcode);
}
-int frsh_synchobj_wait
- (const frsh_synchobj_handle_t synch_handle,
- frsh_rel_time_t *next_budget,
- frsh_rel_time_t *next_period,
- bool *was_deadline_missed,
- bool *was_budget_overrun)
+int frsh_vres_get_usage
+ (const frsh_vres_id_t vres,
+ frsh_rel_time_t *spent)
{
- return FRSH_ERR_NOT_IMPLEMENTED;
+ qres_time_t exec_budget;
+ qos_rv rv;
+
+ rv = qres_get_exec_time(NULL, &exec_budget, NULL);
+ if (rv != QOS_OK) return EINVAL;
+
+ if (spent)
+ *spent = frsh_usec_to_rel_time(exec_budget);
+
+ return 0;
}
-int frsh_synchobj_wait_with_timeout
- (const frsh_synchobj_handle_t synch_handle,
- const frsh_abs_time_t *abs_timeout,
- bool *timed_out,
- frsh_rel_time_t *next_budget,
- frsh_rel_time_t *next_period,
- bool *was_deadline_missed,
- bool *was_budget_overran)
+int frsh_vres_get_job_usage
+ (const frsh_vres_id_t vres,
+ frsh_rel_time_t *spent)
{
- return FRSH_ERR_NOT_IMPLEMENTED;
+ qres_params_t q_params;
+ qres_time_t curr_budget;
+ qos_rv rv;
+
+ rv = qres_get_params(NULL, &q_params);
+ if (rv != QOS_OK) return EINVAL;
+
+ rv = qres_get_curr_budget(NULL, &curr_budget);
+ if (rv != QOS_OK) return EINVAL;
+
+ if (spent)
+ *spent = frsh_usec_to_rel_time(q_params->Q - curr_budget);
+
+ return 0;
}
-int frsh_timed_wait
- (const frsh_abs_time_t *abs_time,
- frsh_rel_time_t *next_budget,
- frsh_rel_time_t *next_period,
- bool *was_deadline_missed,
- bool *was_budget_overran)
+int frsh_vres_get_remaining_budget
+ (const frsh_vres_id_t vres,
+ frsh_rel_time_t *budget)
{
- return FRSH_ERR_NOT_IMPLEMENTED;
+ qres_time_t curr_budget;
+ qos_rv rv;
+
+ rv = qres_get_curr_budget(NULL, &curr_budget);
+ if (rv != QOS_OK) return EINVAL;
+
+ if (budget)
+ *budget = frsh_usec_to_rel_time(curr_budget);
+
+ return 0;
}
#include <frsh_error.h>
#include <fres_vres.h>
+#include <fra_generic.h>
#include <libcgroup.h>
/* local timepsec <-> usec utility macros */
{
struct cgroup* cgroup = (struct cgroup*)vres->priv;
struct sched_param param;
+ int ret;
/*if (!aqcpu_is_initialized) {
return(FRSH_ERR_NOT_INITIALIZED);
}*/
-
+
+ ret = fra_insert_thread_vres(&thread, vres);
+ if (ret) goto err;
if (cgroup_attach_task_pid(cgroup, thread.linux_tid)) {
return FRSH_ERR_INTERNAL_ERROR;
}
}*/
- return FRSH_NO_ERROR;
+ return FRSH_NO_ERROR;
+err:
+ return FRSH_ERR_INTERNAL_ERROR;
}
/*
*/
int frsh_thread_unbind(const frsh_thread_id_t thread)
{
+ int ret;
/* TODO: solve thread -> vres mapping */
#if 0
char path[FILENAME_MAX];
}
fclose(taskf);
#endif
- return FRSH_NO_ERROR;
+
+ ret = fra_delete_thread_vres(&thread);
+ if (ret) goto err;
+
+ return FRSH_NO_ERROR;
+err:
+ return FRSH_ERR_INTERNAL_ERROR;
}
/**
return (wp.errcode);
}
-int frsh_synchobj_wait
- (const frsh_synchobj_handle_t synch_handle,
- frsh_rel_time_t *next_budget,
- frsh_rel_time_t *next_period,
- bool *was_deadline_missed,
- bool *was_budget_overrun)
+int frsh_vres_get_usage
+ (const frsh_vres_id_t vres,
+ frsh_rel_time_t *spent)
{
return FRSH_ERR_NOT_IMPLEMENTED;
}
-int frsh_synchobj_wait_with_timeout
- (const frsh_synchobj_handle_t synch_handle,
- const frsh_abs_time_t *abs_timeout,
- bool *timed_out,
- frsh_rel_time_t *next_budget,
- frsh_rel_time_t *next_period,
- bool *was_deadline_missed,
- bool *was_budget_overran)
+int frsh_vres_get_job_usage
+ (const frsh_vres_id_t vres,
+ frsh_rel_time_t *spent)
{
return FRSH_ERR_NOT_IMPLEMENTED;
}
-int frsh_timed_wait
- (const frsh_abs_time_t *abs_time,
- frsh_rel_time_t *next_budget,
- frsh_rel_time_t *next_period,
- bool *was_deadline_missed,
- bool *was_budget_overran)
+int frsh_vres_get_remaining_budget
+ (const frsh_vres_id_t vres,
+ frsh_rel_time_t *budget)
{
return FRSH_ERR_NOT_IMPLEMENTED;
}