]> rtime.felk.cvut.cz Git - frescor/frsh.git/commitdiff
Add support for multi (CPU and DISK) resources.
authorDario <dario@dario-desktop.(none)>
Thu, 30 Apr 2009 09:15:15 +0000 (11:15 +0200)
committerDario <dario@dario-desktop.(none)>
Thu, 30 Apr 2009 09:15:15 +0000 (11:15 +0200)
This quite disruptive commit the support for multiple
resources is introduced into the FRSH-FORB architecture.

For now, only CPU and DISK resources are supported, but, as usual,
the framework is flexible enough to make the adding of new resources
as easy as possible.

Unfortunately, we have not been able (yet), mainly for time reasons,
to go with the framework's usual ORB and virtual function based approach,
and some switch/case logic has been added in FRSH API implementation. :-(
We think this approach could anyway be valuable, at least for now...
Refinements and more "clean" solutions may come in the future, and any
kind of suggestion is welcome with this respect.

12 files changed:
frsh_api/frsh_feedback.c [new file with mode: 0644]
frsh_api/frsh_thread.c
frsh_api/frsh_vres.c
resources/cpu_aquosa/lib/Makefile.omk
resources/cpu_aquosa/lib/aqcpu_fra.c
resources/cpu_aquosa/lib/aqcpu_res.h
resources/cpu_aquosa/lib/frsh_aqcpu.c [deleted file]
resources/cpu_aquosa/tests/aqcputest.c
resources/cpucg/lib/Makefile.omk
resources/cpucg/lib/cpucg_fra.c
resources/cpucg/lib/cpucg_res.h
resources/cpucg/lib/frsh_cpucg.c [deleted file]

diff --git a/frsh_api/frsh_feedback.c b/frsh_api/frsh_feedback.c
new file mode 100644 (file)
index 0000000..e9d0df7
--- /dev/null
@@ -0,0 +1,199 @@
+/**************************************************************************/
+/* ---------------------------------------------------------------------- */
+/* 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_feedback.c
+ * @author Dario Faggioli <faggioli@gandalf.sssup.it>
+ * @date   Wed Feb 20 14:53:22 2009
+ * 
+ * @brief  Feedback module of FRSH_FORB framework
+ * 
+ */
+
+#include <frsh_core.h>
+#include <fra_generic.h>
+#include "frsh_forb.h"
+#include <frsh_resources.h>
+
+#ifdef CONFIG_AQUOSA
+#include <aqcpu_res.h>
+#endif
+#ifdef CONFIG_CPUCG
+#include <cpucg_res.h>
+#endif
+#ifdef CONFIG_DISKBFQ
+#include <diskbfq_res.h>
+#endif
+
+static frsh_vres_id_t spare_vres;
+
+int frsh_feedback_get_spare(frsh_contract_t *spare_contract)
+{
+       return frsh_vres_get_contract(spare_vres, spare_contract);
+}
+
+int frsh_feedback_set_spare
+  (const frsh_contract_t *spare_contract)
+{
+       int ret = 0;
+       fres_block_basic *b;
+
+       if (!spare_contract || !*spare_contract)
+               return FRSH_ERR_BAD_ARGUMENT;
+
+       ret = frsh_contract_negotiate(spare_contract, &spare_vres);
+       if (ret) goto err;
+
+       b = fres_contract_get_basic(*spare_contract);
+       switch(r->resource_type)
+       {
+               case FRSH_RT_CPU:
+               {
+                       ret = fra_CPU_set_spare_bandwidth(vres_id);
+                       break;
+               }
+               case FRSH_RT_DISK:
+               {
+                       ret = fra_DISK_set_spare_bandwidth(vres_id);
+                       break;
+               }
+       }
+
+       return ret;
+}
+
+int frsh_feedback_get_desired_budget
+  (frsh_vres_id_t vres_id,
+   frsh_rel_time_t *p_budget_out)
+{
+       frsh_contract_t *contract = vres->percieved;
+       fres_block_resource *r = fres_contract_get_resource(*contract);
+       int ret;
+
+       switch(r->resource_type)
+       {
+               case FRSH_RT_CPU:
+               {
+                       ret = fra_CPU_get_desired_budget(vres, p_budget_out);
+                       break;
+               }
+               case FRSH_RT_DISK:
+               {
+                       ret = fra_DISK_get_desired_budget(vres, p_budget_out);
+                       break;
+               }
+               default:
+                       goto err;
+       }
+       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)
+{
+       frsh_contract_t *contract = vres->percieved;
+       fres_block_resource *r = fres_contract_get_resource(*contract);
+       int ret;
+
+       switch(r->resource_type)
+       {
+               case FRSH_RT_CPU:
+               {
+                       ret = fra_CPU_set_desired_budget(vres, p_budget_in);
+                       break;
+               }
+               case FRSH_RT_DISK:
+               {
+                       ret = fra_DISK_set_desired_budget(vres, p_budget_in);
+                       break;
+               }
+               default:
+                       goto err;
+       }
+
+       if (err) 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)
+{
+       frsh_contract_t *contract = vres->percieved;
+       fres_block_resource *r = fres_contract_get_resource(*contract);
+       int ret;
+
+       switch(r->resource_type)
+       {
+               case FRSH_RT_CPU:
+               {
+                       ret = fra_CPU_get_actual_budget(vres, budget);
+                       break;
+               }
+               case FRSH_RT_DISK:
+               {
+                       ret = fra_DISK_get_actual_budget(vres, budget);
+                       break;
+               }
+               default:
+                       goto err;
+       }
+
+       if (err) goto err;
+
+       return FRSH_NO_ERROR;
+err:
+       return FRSH_ERR_INTERNAL_ERROR;
+}
+
index dfddb5c530741e81ddd276762be30ccb3308eb87..d5c89fb01cdcc4828d24ba400a68e5f43623eec6 100644 (file)
@@ -6,6 +6,8 @@
  *
  *
  */
+#include <semaphore.h>
+
 #include <fres_contract.h>
 #include <fres_contract_idl.h>
 #include <frsh_core.h>
 #include <fres_blocks.h>
 #include <string.h>
 #include <fcb.h>
-#include "frsh_forb.h"
 #include <fra_generic.h>
 
+#include "frsh_forb.h"
+
+#ifdef CONFIG_AQUOSA
+#include <aqcpu_res.h>
+#endif
+#ifdef CONFIG_CPUCG
+#include <cpucg_res.h>
+#endif
+#ifdef CONFIG_DISKBFQ
+#include <diskbfq_res.h>
+#endif
+
+/**
+ * frsh_thread_bind(), bind a thread to a vres
+ *
+ * possible return values:
+ *  FRSH_NO_ERROR
+ *  FRSH_ERR_NOT_INITIALIZED
+ *  FRSH_BAD_ARGUMENT(*) (invalid or dummy vres)
+ *  FRSH_ERR_NOT_CONTRACTED_VRES(*)
+ *  FRSH_ERR_ALREADY_BOUND(*)
+ *  FRSH_ERR_INTERNAL_ERROR(*) (something wrong with AQuoSA or with the service thread internal data structures)
+ */
+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);
+       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 (ret) goto err_delete;
+
+       return FRSH_NO_ERROR;
+
+err_delete:
+       fra_delete_thread_vres(&thread, r->resource_type);
+err:
+       return FRSH_ERR_INTERNAL_ERROR;
+}
+
+/*
+ * frsh_thread_unbind(), unbind a thread from a vres
+ *
+ * @FIXME:
+ *  Notice that, since we don't know from which VRES the
+ *   thread should be unbound, we unboind it from all the
+ *   ones it is attached to!
+ *
+ * possible return values:
+ *  FRSH_NO_ERROR
+ *  FRSH_ERR_NOT_INITIALIZED
+ *  FRSH_BAD_ARGUMENT(*) (invalid thread)
+ *  FRSH_ERR_NOT_BOUND(*)
+ *  FRSH_ERR_INTERNAL_ERROR(*) (something wrong with AQuoSA or with the service thread internal data structures)
+ */
+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 (ret) goto err;
+
+               ret = fra_delete_thread_vres(&thread, FRSH_RT_PROCESSOR);
+               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 (ret) goto err;
+
+               ret = fra_delete_thread_vres(&thread, FRSH_RT_DISK);
+               if (ret) goto err;
+       }
+
+       return FRSH_NO_ERROR;
+err:
+       return FRSH_ERR_INTERNAL_ERROR;
+}
+
+/**
+ * structure used to pass the new created thread (or better its wrapper) the
+ * arguments it needs to bind itself to the vres.
+ */
+typedef struct wrapper_pthread_arg {
+       frsh_thread_id_t parent_thread_id;
+       frsh_thread_id_t *thread_id;
+       frsh_thread_code_t pthread_code;        /**< function to be running in thread */
+       void *pthread_arg;                      /**< thread arguments*/
+       frsh_vres_id_t vres;
+       sem_t *stopper;                         /**< semaphore to synchronize frsh call and wrapper thread */
+       int  errcode;
+} wrapper_pthread_arg_t;
+
+/*
+ * typedef struct {
+ *     pthread_t pthread_id;
+ *     pid_t linux_pid;
+ *     pid_t linux_tid;
+ * } FOSA_THREAD_ID_T_OPAQUE;
+ */
+
+/**
+ * Wrapper thread
+ * 
+ * possible exit status:
+ *  FRSH_ERR_INTENRAL_ERROR (something wrong with threads and signal handling)
+ *  FRSH_ERR_TOO_MANY_TASKS(*)
+ *  FRSH_ERR_BAD_ARGUMENT(*) (invalid vres)
+ *  FRSH_ERR_NOT_CONTRACTED_VRES(*)
+ *  whatever the user provided code 'pthread_code' returns
+ */
+static void* wrapper_pthread(void *arg)
+{
+       wrapper_pthread_arg_t* pth = (wrapper_pthread_arg_t*) arg;
+       frsh_thread_id_t* thread_id = pth->thread_id;
+       void *thread_arg = pth->pthread_arg;
+       frsh_thread_code_t thread_code = pth->pthread_code;
+
+       /* bind this thread to vres */
+       *thread_id = fosa_thread_self();
+       pth->errcode = frsh_thread_bind(pth->vres, *thread_id);
+
+       sem_post(pth->stopper);
+       /* No access to pth is allowed after this point, it can vanish already */
+
+       if (pth->errcode) return NULL;
+
+       /* execute thread code */
+       return thread_code(thread_arg);
+}
+
+/*
+ * API call for 'frsh_thread_create_and_bind()', as said prepares the
+ * wrapper code argument data structure, create the new thread and wait
+ * its acknowledgment before stepping over
+ *
+ * possible return values:
+ *  FRSH_NO_ERROR
+ *  FRSH_ERR_NOT_INITIALIZED
+ *  FRSH_ERR_BAD_ARGUMENT (NULL thread or thread_code)
+ *  whatever 'fosa_thread_create()' returns
+ *  FRSH_ERR_INTERNAL_ERROR 
+ */
+int frsh_thread_create_and_bind
+  (const frsh_vres_id_t vres,
+   frsh_thread_id_t *thread,
+   frsh_thread_attr_t *attr,
+   frsh_thread_code_t thread_code,
+   void *arg)
+{
+       wrapper_pthread_arg_t wp_arg;
+       sem_t stopper;
+       int ret;
+
+       sem_init(&stopper, 0, 0);
+
+       if (!thread || !thread_code || !attr)
+               return FRSH_ERR_BAD_ARGUMENT;
+
+       wp_arg.parent_thread_id = fosa_thread_self();
+       wp_arg.thread_id = thread;
+       wp_arg.pthread_code = thread_code;
+       wp_arg.pthread_arg = arg;
+       wp_arg.vres = vres;
+       wp_arg.stopper = &stopper;
+
+       /* create the wrapper thread */
+       pthread_attr_setinheritsched(attr, PTHREAD_EXPLICIT_SCHED);
+       pthread_attr_setscope(attr, PTHREAD_SCOPE_SYSTEM);
+       ret = fosa_thread_create(thread, attr, wrapper_pthread,
+                               (void*)&wp_arg);
+
+       if (ret != 0)
+               return(ret);
+
+       sem_wait(&stopper);
+
+       return (wp_arg.errcode);
+}
+
 int frsh_thread_create_in_background
   (frsh_thread_code_t thread_code,
    const void *thread_arg,
@@ -26,7 +237,7 @@ int frsh_thread_create_in_background
 {
        frsh_contract_t contract;
        fosa_rel_time_t zero_msec = fosa_msec_to_rel_time(0);
-       int rv = 0;
+       int ret = 0;
 
        /* Background contract creation and negotiation */
        frsh_contract_init(&contract);
@@ -41,15 +252,18 @@ int frsh_thread_create_in_background
                                       FRSH_CT_BACKGROUND);
 
        /* It will be accepted: we are asking for 0 budget over 0 period */
-       rv = frsh_contract_negotiate(&contract, vres_id);
-       if (rv !=0) goto error;
+       ret = frsh_contract_negotiate(&contract, vres_id);
+       if (ret !=0) goto error;
+
+       ret = fosa_thread_create(thread, attr, thread_code, (void*) thread_arg);
+       if (ret != 0) goto error;
 
-       rv = fosa_thread_create(thread, attr, thread_code, (void*) thread_arg);
-       if (rv != 0) goto error;
+       ret = fra_insert_thread_vres(thread, FRSH_RT_PROCESSOR, *vres_id);
+       if (ret) goto error;
 
        return 0;
 error:
-       return rv;
+       return ret;
 }
 
 int frsh_thread_get_vres_id
@@ -59,7 +273,12 @@ int frsh_thread_get_vres_id
        if (!vres_id)
                return FRSH_ERR_BAD_ARGUMENT;
 
-       *vres_id = fra_get_vres_thread_vres(&thread, FRSH_RT_PROCESSOR);
+       /*
+        * @FIXME:
+        *  Why PROCESSOR and not DISK or NETWORK (or whatever) ??
+        */
+       *vres_id = fra_get_vres_thread_vres(&thread,
+                                           FRSH_RT_PROCESSOR);
 
        return vres_id ? 0 : EINVAL;
 }
index 1389a8370937939eef90d8271b9a7482aaacad7c..c28e125174d09c947285abce33022d2217cbe991 100644 (file)
 
 #include <frsh_core.h>
 #include <fra_generic.h>
-#include "frsh_forb.h"
 #include <frsh_resources.h>
 
+#include "frsh_forb.h"
+
+#ifdef CONFIG_AQUOSA
+#include <aqcpu_res.h>
+#endif
+#ifdef CONFIG_CPUCG
+#include <cpucg_res.h>
+#endif
+#ifdef CONFIG_DISKBFQ
+#include <diskbfq_res.h>
+#endif
+
 int frsh_vres_get_priority
   (frsh_vres_id_t vres_id,
    int *priority)
@@ -84,7 +95,26 @@ int frsh_resource_get_vres_from_label
    const frsh_resource_id_t resource_id,
    frsh_vres_id_t *vres)
 {
-       return FRSH_ERR_NOT_IMPLEMENTED;
+       fres_block_resource *r;
+       fres_block_label *label;
+
+       r = malloc(sizeof(*r));
+       if (!r) return ENOMEM;
+       r->resource_type = resource_type;
+       r->resource_id = resource_id;
+
+       label = malloc(sizeof(*label));
+       if (!label) {
+               free(r);
+               return ENOMEM;
+       }
+       strncpy(label->label, contract_label, sizeof(label->label));
+       label->label[sizeof(label->label)-1] = '\0';
+
+       vres = fres_vreses_find_label(label, r);
+       if (vres) return FRSH_NO_ERROR;
+
+       return FRSH_ERR_CONTRACT_LABEL_UNKNOWN;
 }
 
 int frsh_vres_get_renegotiation_status
@@ -123,3 +153,93 @@ int frsh_vres_get_budget_and_period
        return 0;
 }
 
+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 (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 (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 (ret) goto err;
+
+       return FRSH_NO_ERROR;
+err:
+       return FRSH_ERR_INTERNAL_ERROR;
+}
+
index 2a12dc0fc3fda7413e90232ad248e17b9fc596f5..60602f0a6fcf142da7848ecb04c3f9d5c393d7a5 100644 (file)
@@ -2,6 +2,6 @@ shared_LIBRARIES = frshaqcpu
 CFLAGS += -I $(AQUOSA_ROOT)/include
 LOADLIBES += -L $(AQUOSA_ROOT)/lib
 LOADLIBES += -Xlinker -rpath -Xlinker $(AQUOSA_ROOT)/lib
-frshaqcpu_SOURCES += frsh_aqcpu.c aqcpu_contract.c aqcpu_fra.c 
+frshaqcpu_SOURCES += aqcpu_contract.c aqcpu_fra.c 
 include_HEADERS += aqcpu_contract.h aqcpu_res.h
 frshaqcpu_LIBS += qreslib qsuplib
index 1e03ccabc005561e588f5f03de57daa16882897e..458d6c6185f881bb8821d7d3e9390acb6d504b82 100644 (file)
@@ -59,6 +59,8 @@
 #include <fra_generic.h>
 
 #include "aquosa/qres_lib.h"
+#include "aquosa/qsup_lib.h"
+
 #include "aqcpu_contract.h"
 
 UL_LOG_CUST(ulogd_fra_aqcpu);
@@ -208,7 +210,7 @@ int aqcpu_fra_init(void)
                errno = -EPERM;
                return -1;
        }
-       
+
        if ((rv = fra_register(&aqcpu_allocator))) {
                qres_cleanup();
                return rv;
@@ -231,3 +233,180 @@ int aqcpu_fra_exit()
        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_get_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;
+}
+
index f316b43c408740e137c2367661c2718705f5fb8a..796ea292fcf1a78783f1bd757e568ba14be6f485 100644 (file)
 #ifndef AQCPU_RES_H
 #define AQCPU_RES_H
 
+#include <fres_vres.h>
+
 #include <forb.h>
 #include <fcb.h>
-#include <frsh_core.h>
 
 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_get_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 */
 
diff --git a/resources/cpu_aquosa/lib/frsh_aqcpu.c b/resources/cpu_aquosa/lib/frsh_aqcpu.c
deleted file mode 100644 (file)
index 5e3c8ef..0000000
+++ /dev/null
@@ -1,455 +0,0 @@
-// -----------------------------------------------------------------------
-//  Copyright (C) 2006 - 2007 by the FRESCOR consortium:
-//
-//    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
-//
-//           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.
-//
-//
-//  based on previous work (FSF) done in the FIRST project
-//                       
-//   Copyright (C) 2005  Mälardalen University, SWEDEN
-//                       Scuola Superiore S.Anna, ITALY
-//                       Universidad de Cantabria, SPAIN
-//                       University of York, UK
-//
-//   FSF API web pages: http://marte.unican.es/fsf/docs
-//                      http://shark.sssup.it/contrib/first/docs/
-//
-//  This file is part of FRSH API
-//
-//  FRSH API is free software; you can  redistribute it and/or  modify
-//  it under the 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 API  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
-//  distributed  with  FRSH API;  see file COPYING.   If not,  write to the
-//  Free Software  Foundation,  59 Temple Place  -  Suite 330,  Boston, MA
-//  02111-1307, USA.
-//
-//  As a special exception, if you include this header file into source
-//  files to be compiled, this header file does not by itself cause
-//  the resulting executable 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 General
-//  Public License.
-// -----------------------------------------------------------------------
-//==============================================
-//  ******** *******    ********  **      **
-//  **///// /**////**  **//////  /**     /**
-//  **      /**   /** /**        /**     /**
-//  ******* /*******  /********* /**********
-//  **////  /**///**  ////////** /**//////**
-//  **      /**  //**        /** /**     /**
-//  **      /**   //** ********  /**     /**
-//  //       //     // ////////   //      // 
-//
-// FRSH(FRescor ScHeduler), pronounced "fresh"
-//==============================================
-
-/*
- * frsh_aqcpu.c
- *
- * This file contains the implementation of FRSH API core functions on top
- * of the AQuoSA framework, on GNU/Linux platform.
- *
- */
-
-/* Linux files */
-#include <unistd.h>
-#include <linux/unistd.h>
-#include <errno.h>
-#include <sys/types.h>
-#ifndef _XOPEN_SOURCE
-#  define _XOPEN_SOURCE 500
-#endif
-#ifndef __USE_UNIX98
-#  define __USE_UNIX98
-#endif
-#include <pthread.h>
-#include <semaphore.h>
-#include <stdio.h>
-#include <string.h>
-
-/* FRSH files */
-#include <frsh_cpp_macros.h>
-#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>
-#include <aquosa/qsup_lib.h>
-
-
-/**
- * structure used to pass the new created thread (or better its wrapper) the
- * arguments it needs to bind itself to the vres.
- */
-typedef struct {
-       frsh_thread_id_t parent_thread_id;
-       frsh_thread_id_t *thread_id;
-       frsh_thread_code_t pthread_code; /**< function to be running in thread */
-       void *pthread_arg;               /**< thread arguments*/
-       frsh_vres_id_t vres;
-       sem_t *stopper; /**< semaphore to synchronize frsh call and wrapper thread */
-       int  errcode;
-} wrapper_pthread_arg_t;
-
-/*typedef struct {
-               pthread_t pthread_id;
-               pid_t linux_pid;
-               pid_t linux_tid;
-} FOSA_THREAD_ID_T_OPAQUE;*/
-
-/**
- * frsh_thread_bind(), bind a thread to a vres
- *
- * possible return values:
- *  FRSH_NO_ERROR
- *  FRSH_ERR_NOT_INITIALIZED
- *  FRSH_BAD_ARGUMENT(*) (invalid or dummy vres)
- *  FRSH_ERR_NOT_CONTRACTED_VRES(*)
- *  FRSH_ERR_ALREADY_BOUND(*)
- *  FRSH_ERR_INTERNAL_ERROR(*) (something wrong with AQuoSA or with the service thread internal data structures)
- */
-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);
-
-       /*if (!aqcpu_is_initialized) {
-                 return(FRSH_ERR_NOT_INITIALIZED);
-       }*/
-
-       ret = fra_insert_thread_vres(&thread, FRSH_RT_PROCESSOR, vres);
-       if (ret) goto err;
-
-       if ((qrv = qres_attach_thread(sid, thread.linux_pid, 
-               thread.linux_tid)) != QOS_OK)
-                       goto err_delete;
-
-       return FRSH_NO_ERROR;
-
-err_delete:
-       fra_delete_thread_vres(&thread, FRSH_RT_PROCESSOR);
-err:
-       return FRSH_ERR_INTERNAL_ERROR;
-}
-
-/*
- * frsh_thread_unbind(), unbind a thread from a vres
- *
- * possible return values:
- *  FRSH_NO_ERROR
- *  FRSH_ERR_NOT_INITIALIZED
- *  FRSH_BAD_ARGUMENT(*) (invalid thread)
- *  FRSH_ERR_NOT_BOUND(*)
- *  FRSH_ERR_INTERNAL_ERROR(*) (something wrong with AQuoSA or with the service thread internal data structures)
- */
-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)
-               goto err;
-
-       ret = fra_delete_thread_vres(&thread, FRSH_RT_PROCESSOR);
-       if (ret) goto err;
-
-       if ((qrv = qres_detach_thread(sid, thread.linux_pid, 
-               thread.linux_tid)) != QOS_OK)
-               goto err;
-
-       return FRSH_NO_ERROR; 
-err:
-       return FRSH_ERR_INTERNAL_ERROR;
-}
-
-/**
- * Wrapper thread
- * 
- * possible exit status:
- *  FRSH_ERR_INTENRAL_ERROR (something wrong with threads and signal handling)
- *  FRSH_ERR_TOO_MANY_TASKS(*)
- *  FRSH_ERR_BAD_ARGUMENT(*) (invalid vres)
- *  FRSH_ERR_NOT_CONTRACTED_VRES(*)
- *  whatever the user provided code 'pthread_code' returns
- */
-static void* wrapper_pthread(void *arg)
-{
-       wrapper_pthread_arg_t* pth = (wrapper_pthread_arg_t*) arg;      
-       frsh_thread_id_t* thread_id = pth->thread_id;   
-       void *thread_arg = pth->pthread_arg;
-       frsh_thread_code_t thread_code = pth->pthread_code;
-       int  errcode;
-       
-       *thread_id = fosa_thread_self();
-       /* bind this thread to vres */
-       errcode = frsh_thread_bind(pth->vres, *thread_id);
-       pth->errcode = errcode;
-       
-       sem_post(pth->stopper); 
-       /* No access to pth is allowed after this point, it can vanish already */
-
-       if (errcode) /* vres binding was not successful */
-               return NULL;
-
-       /* execute thread function */   
-       return thread_code(thread_arg);
-}
-
-/*
- * frsh_thread_bind(), create a new thread and bind it to a vres
- * frsh_thread_create_in_background(), create a new thread and a new BACKGROUND contract 
- * and bind them
- *
- * The two functions both create a new thread and bind it to a vres, existing
- * fr the former, created for the latter.
- *
- * The implementation uses a wrapper function as the new thread code (it's
- * the simplest way to handle some issues on POSIX 'pthread_t' and
- * 'pthread_self()', for a detailed explanation of the "problem" ask the
- * authors via e-mail) which, on its turn, bind itself to the vres and then
- * run the user provided code. The API calls simply create the new thread,
- * using the wrapper thread code, and return.
- *
- * Note that in order to return the caller the descriptor of the new created
- * thread (known to the wrapped thread but not entirely to the API calls) a
- * special 'struct' data type is passed as the parameter of the wrapper thread
- * and a simple synchronization mechanism based on semaphore is realized.
- *
- * possible return values:
- *  see below the comments of each specific API call
- */
-
-/*
- * API call for 'frsh_thread_create_and_bind()', as said prepares the
- * wrapper code argument data structure, create the new thread and wait
- * its acknowledgment before stepping over
- *
- * possible return values:
- *  FRSH_NO_ERROR
- *  FRSH_ERR_NOT_INITIALIZED
- *  FRSH_ERR_BAD_ARGUMENT (NULL thread or thread_code)
- *  whatever 'fosa_thread_create()' returns
- *  FRSH_ERR_INTERNAL_ERROR 
- */
-int frsh_thread_create_and_bind(const frsh_vres_id_t vres,
-       frsh_thread_id_t *thread,
-       frsh_thread_attr_t *attr,
-       frsh_thread_code_t thread_code,
-       void *arg)
-{
-       wrapper_pthread_arg_t wp;
-       int rv;
-       sem_t stopper; 
-
-       sem_init(&stopper, 0, 0);
-       
-       /* check for framework initialization and arguments */
-       /*if (!frsh_initialized)
-               PERROR_AND_RETURN(FRSH_ERR_NOT_INITIALIZED,
-               "can't proceed before initializing FRSH with 'frsh_init()'!");
-       if ((thread == NULL) || (thread_code == NULL))
-               PERROR_AND_RETURN(FRSH_ERR_BAD_ARGUMENT,
-               "can't create a thread with NULL thread_core or return it in a NULL thread");
-       */
-
-       wp.parent_thread_id = fosa_thread_self();
-       wp.thread_id = thread;  
-       wp.pthread_code = thread_code;
-       wp.pthread_arg = arg;   
-       wp.vres = vres;
-       wp.stopper = &stopper;
-
-       /* create the wrapper thread */ 
-       rv = fosa_thread_create(thread, attr, wrapper_pthread, (void*)&wp);
-       if (rv != 0)
-               return(rv);
-       
-       sem_wait(&stopper);
-       return (wp.errcode);
-}
-
-int frsh_vres_get_usage
-  (const frsh_vres_id_t vres,
-   frsh_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 = frsh_usec_to_rel_time(exec_budget);
-
-       return 0;
-}
-
-int frsh_vres_get_job_usage
-  (const frsh_vres_id_t vres,
-   frsh_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 = frsh_usec_to_rel_time(q_params.Q - curr_budget);
-
-       return 0;
-}
-
-int frsh_vres_get_remaining_budget
-  (const frsh_vres_id_t vres,
-   frsh_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 = frsh_usec_to_rel_time(curr_budget);
-
-       return 0;
-}
-
-int frsh_feedback_get_spare
-  (frsh_contract_t *spare_contract)
-{
-       /**
-        * TODO:
-        *  retreive the special feedback contract.
-        */
-       return FRSH_ERR_NOT_IMPLEMENTED;
-}
-
-int frsh_feedback_set_spare
-  (const frsh_contract_t *spare_contract)
-{
-       int ret = 0;
-       frsh_vres_id_t vres_id;
-       fres_block_basic *b;
-       qos_rv rv;
-
-       if (!spare_contract || !*spare_contract)
-               return FRSH_ERR_BAD_ARGUMENT;
-
-       ret = frsh_contract_negotiate(spare_contract, &vres_id);
-       if (ret) goto err;
-
-       b = fres_contract_get_basic(*spare_contract);
-       if (!b) return EINVAL;
-       rv = qsup_reserve_spare(r2bw(frsh_rel_time_to_usec(b->budget), frsh_rel_time_to_usec(b->period)));
-       if (rv != QOS_OK) return EINVAL;
-
-err:
-       return ret;
-}
-
-int frsh_feedback_get_desired_budget
-  (frsh_vres_id_t vres_id,
-   frsh_rel_time_t *p_budget_out)
-{
-       qres_sid_t sid = *((qres_sid_t*) vres_id->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 = frsh_usec_to_rel_time(q_params.Q);
-
-       return 0;
-}
-
-int frsh_feedback_set_desired_budget
-  (frsh_vres_id_t vres_id,
-   frsh_rel_time_t *p_budget_in)
-{
-       qres_sid_t sid = *((qres_sid_t*) vres_id->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 = frsh_rel_time_to_usec(*p_budget_in);
-
-       rv = qres_set_params(sid, &q_params);
-       if (rv != QOS_OK) return EINVAL;
-
-       return 0;
-}
-
-int frsh_feedback_get_actual_budget
-  (frsh_vres_id_t vres_id,
-   frsh_rel_time_t *budget)
-{
-       qres_sid_t sid = *((qres_sid_t*) vres_id->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 = frsh_usec_to_rel_time(appr_budget);
-
-       return 0;
-}
-
index dcb530250b3858bbb622e7767bf063c25ac0c5d0..fadaa2f59db9974fa3f4a6060d12bac724ddd06b 100644 (file)
@@ -4,15 +4,29 @@
 
 void* work_thread()
 {
-       int i;
+       int ret;
+       unsigned long i = 0;
+       frsh_vres_id_t vres_id;
 
        printf("I am alive! \n");
-       while(1) {
-               printf("I am alive! \n");
+       while(i != 1E9) {
                i++;
 
+               printf("I am alive, run %lu!\n", i);
+
+               ret = frsh_thread_get_vres_id(fosa_thread_self(), &vres_id);
+               if (ret) PERROR_AND_EXIT(ret, "frsh_get_vres_id");
+               printf("\tvres retrieved from thread-ID: %d\n", (int) vres_id);
+
+               ret = frsh_resource_get_vres_from_label("TEST_VRES",
+                                                       FRSH_RT_PROCESSOR,
+                                                       0,
+                                                       &vres_id);
+               if (ret) PERROR_AND_EXIT(ret, "frsh_get_vres_from_label");
+               printf("\ton retrived from label: %d\n", (int) vres_id);
        }
 
+       return EXIT_SUCCESS;
 }
 
 int main()
@@ -24,17 +38,15 @@ int main()
        frsh_rel_time_t budget, period;
        int ret;
 
-       if (frsh_init()) {
+       if (frsh_init())
                error(1, 0, "FRSH initialization failed\n");
-
-       }
        
        /* Contract negotiation for CPU */
        ret = frsh_contract_init(&contract);
        if (ret) PERROR_AND_EXIT(ret, "frsh_contract_init");
                
        budget = fosa_msec_to_rel_time(10);
-       period = fosa_msec_to_rel_time(2000);
+       period = fosa_msec_to_rel_time(100);
        ret = frsh_contract_set_basic_params(&contract,
                                             &budget,
                                             &period,
@@ -42,19 +54,23 @@ int main()
                                             FRSH_CT_REGULAR);
        if (ret) PERROR_AND_EXIT(ret, "frsh_contract_set_basic_params");
        ret = frsh_contract_set_resource_and_label(&contract, FRSH_RT_PROCESSOR,
-                                                       0,"aqcpu_cont1");
+                                                       0,"TEST_VRES");
        if (ret) PERROR_AND_EXIT(ret, "frsh_contract_set_resource_and_label");
 
        ret = frsh_contract_negotiate(&contract, &vres);
        if (ret) PERROR_AND_EXIT(ret, "frsh_contract_negotiate");
 
-       printf("Aqcpu vres negotiated\n");
+       printf("Aqcpu vres negotiated, vres-ID: %d\n", (int) vres);
        pthread_attr_init(&attr);
        ret = frsh_thread_create_and_bind(vres, &thread, &attr, 
                                work_thread, (void*) NULL);
        if (ret) PERROR_AND_EXIT(ret, "frsh_thread_create_and_bind");
        
        pthread_join(thread.pthread_id, (void**) NULL); 
+
+       ret = frsh_contract_cancel(vres);
+       if (ret) PERROR_AND_EXIT(ret, "frsh_contract_cancel");
+
        printf("Test PASSED!\n");
                
        return 0;       
index 451dc026b4c34b37e0e32f496898d05cb486f5ff..f1dbf6b610bc26aaabf4a761d7418b00d86ab134 100644 (file)
@@ -1,5 +1,5 @@
 shared_LIBRARIES = frshcpucg
-frshcpucg_SOURCES += frsh_cpucg.c cpucg_contract.c cpucg_fra.c 
+frshcpucg_SOURCES += cpucg_contract.c cpucg_fra.c 
 include_HEADERS += cpucg_contract.h cpucg_res.h timespec_usec_ops.h
 frshcpucg_LIBS += cgroup  
 #include_HEADERS +=$(wildcard aquosa/qresmod/*.h)
index 80bb14f662c902a56eecd50d1217d355015c2106..69d3216892a27d1f86874eea17bb8e37a5e74ef6 100644 (file)
@@ -178,6 +178,8 @@ int cpucg_change_vres(fres_vres_t *vres, void *priv)
        return 0;
 }
 
+
+
 static struct fres_allocator cpucg_allocator = {
        .res_type = FRSH_RT_PROCESSOR,
        .res_id = 0,  /* CPU ID 0 */
@@ -233,3 +235,110 @@ int cpucg_fra_exit()
 {
        return 0;
 }
+
+int fra_CPU_bind_thread
+  (const fres_vres_t vres,
+   const fosa_thread_id_t thread)
+{
+       struct cgroup* cgroup = (struct cgroup*)vres->priv;
+       struct sched_param param;
+       int p, policy, ret;
+
+       /* if (!aqcpu_is_initialized) {
+        *      return(FRSH_ERR_NOT_INITIALIZED);
+        * }
+        */
+
+       pthread_getschedparam(pthread_self(), &policy, &param);
+       p = param.sched_priority;
+       printf("policy = %d, priority = %d\n", policy, p);
+       if (p == 0) {
+               param.sched_priority = 1;
+               pthread_setschedparam(pthread_self(), SCHED_RR, &param);
+               pthread_getschedparam(pthread_self(), &policy, &param);
+               printf("changed policy = %d, changed priority = %d\n",
+                       policy, param.sched_priority);
+       }
+
+       if (cgroup_attach_task_pid(cgroup, thread.linux_tid))
+               goto err;
+
+       return 0;
+err:
+       return -1;
+}
+
+int fra_CPU_unbind_thread(const fosa_thread_id_t thread)
+{
+       int ret;
+
+       /* TODO: solve thread -> vres mapping */
+#if 0
+       char path[FILENAME_MAX];
+       struct cgroup* cgroup = (struct cgroup*)vres->priv;
+       FILE* taskf;
+
+       /* if (!aqcpu_is_initialized) {
+        *      return(FRSH_ERR_NOT_INITIALIZED);
+        * }
+        */
+
+       if (!cg_build_path(cgroup->name, path, cgroup->controller[i]->name)){
+               return FRSH_ERR_INTERNAL_ERROR;
+       }
+
+       strcat(path, "tasks");
+       taskf = fopen(path, "w");
+       if (!taskf) {
+               return FRSH_ERR_INTERNAL_ERROR;
+       }
+       fclose(taskf);
+#endif
+
+       return 0;
+err:
+       return -1;
+}
+
+int fra_CPU_get_usage
+  (const fres_vres_t vres,
+   fosa_rel_time_t *spent)
+{
+       return -1;
+}
+
+int fra_CPU_get_job_usage
+  (const fres_vres_t vres,
+   fosa_rel_time_t *spent)
+{
+       return -1;
+}
+
+int fra_CPU_get_remaining_budget
+  (const fres_vres_t vres,
+   fosa_rel_time_t *budget)
+{
+       return -1;
+}
+
+int fra_CPU_get_desired_budget
+  (fres_vres_t vres,
+   frsh_rel_time_t *p_budget_out)
+{
+       return -1;
+}
+
+int fra_CPU_set_desired_budget
+  (fres_vres_t vres,
+   fosa_rel_time_t *p_budget_in)
+{
+       return -1;
+}
+
+int fra_CPU_get_actual_budget
+  (fres_vres_t vres,
+   fosa_rel_time_t *budget)
+{
+       return -1;
+}
+
index 40cc0c61b69b61ead8e613990bf8f650d267cba5..26a018231a5bbd84091b3db3ba2d8a3e8924c067 100644 (file)
@@ -7,5 +7,29 @@
 
 int cpucg_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 frsh_vres_get_job_usage
+  (const frsh_vres_id_t vres,
+   frsh_rel_time_t *spent)
+{
+        return FRSH_ERR_NOT_IMPLEMENTED;
+}
+
+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_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 /* CPUCG_RES_H */
 
diff --git a/resources/cpucg/lib/frsh_cpucg.c b/resources/cpucg/lib/frsh_cpucg.c
deleted file mode 100644 (file)
index 4539851..0000000
+++ /dev/null
@@ -1,380 +0,0 @@
-// -----------------------------------------------------------------------
-//  Copyright (C) 2006 - 2007 by the FRESCOR consortium:
-//
-//    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
-//
-//           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.
-//
-//
-//  based on previous work (FSF) done in the FIRST project
-//                       
-//   Copyright (C) 2005  Mälardalen University, SWEDEN
-//                       Scuola Superiore S.Anna, ITALY
-//                       Universidad de Cantabria, SPAIN
-//                       University of York, UK
-//
-//   FSF API web pages: http://marte.unican.es/fsf/docs
-//                      http://shark.sssup.it/contrib/first/docs/
-//
-//  This file is part of FRSH API
-//
-//  FRSH API is free software; you can  redistribute it and/or  modify
-//  it under the 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 API  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
-//  distributed  with  FRSH API;  see file COPYING.   If not,  write to the
-//  Free Software  Foundation,  59 Temple Place  -  Suite 330,  Boston, MA
-//  02111-1307, USA.
-//
-//  As a special exception, if you include this header file into source
-//  files to be compiled, this header file does not by itself cause
-//  the resulting executable 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 General
-//  Public License.
-// -----------------------------------------------------------------------
-//==============================================
-//  ******** *******    ********  **      **
-//  **///// /**////**  **//////  /**     /**
-//  **      /**   /** /**        /**     /**
-//  ******* /*******  /********* /**********
-//  **////  /**///**  ////////** /**//////**
-//  **      /**  //**        /** /**     /**
-//  **      /**   //** ********  /**     /**
-//  //       //     // ////////   //      // 
-//
-// FRSH(FRescor ScHeduler), pronounced "fresh"
-//==============================================
-
-/*
- * frsh_aqcpu.c
- *
- * This file contains the implementation of FRSH API core functions on top
- * of the AQuoSA framework, on GNU/Linux platform.
- *
- */
-
-/* Linux files */
-#include <unistd.h>
-#include <linux/unistd.h>
-#include <errno.h>
-#include <sys/types.h>
-#define __USE_UNIX98
-#include <pthread.h>
-#include <semaphore.h>
-#include <stdio.h>
-#include <string.h>
-
-/* FRSH files */
-#include <frsh_cpp_macros.h>
-#include <fosa.h>
-#include <frsh_core_types.h>
-#include <frsh_error.h>
-
-#include <fres_vres.h>
-#include <fra_generic.h>
-#include <libcgroup.h>
-
-/* local timepsec <-> usec utility macros */
-#include "timespec_usec_ops.h"
-
-
-/**
- * structure used to pass the new created thread (or better its wrapper) the
- * arguments it needs to bind itself to the vres.
- */
-typedef struct {
-       frsh_thread_id_t parent_thread_id;
-       frsh_thread_id_t *thread_id;
-       frsh_thread_code_t pthread_code; /**< function to be running in thread */
-       void *pthread_arg;               /**< thread arguments*/
-       frsh_vres_id_t vres;
-       sem_t *stopper; /**< semaphore to synchronize frsh call and wrapper thread */
-       int  errcode;
-} wrapper_pthread_arg_t;
-
-/*typedef struct {
-               pthread_t pthread_id;
-               pid_t linux_pid;
-               pid_t linux_tid;
-} FOSA_THREAD_ID_T_OPAQUE;*/
-
-/**
- * frsh_thread_bind(), bind a thread to a vres
- *
- * possible return values:
- *  FRSH_NO_ERROR
- *  FRSH_ERR_NOT_INITIALIZED
- *  FRSH_BAD_ARGUMENT(*) (invalid or dummy vres)
- *  FRSH_ERR_NOT_CONTRACTED_VRES(*)
- *  FRSH_ERR_ALREADY_BOUND(*)
- *  FRSH_ERR_INTERNAL_ERROR(*) (something wrong with AQuoSA or with the service thread internal data structures)
- */
-int frsh_thread_bind(const frsh_vres_id_t vres, const frsh_thread_id_t thread)
-{
-       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;
-       }
-       
-       /*sched_getparam(thread.linux_tid, &param);
-       if (param.sched_priority == 0) {
-               param.sched_priority = 1;
-               if (sched_setscheduler(thread.linux_tid, SCHED_RR, 
-                       &param) == -1) {
-                       return FRSH_ERR_INTERNAL_ERROR;
-               }
-       }*/
-
-       return FRSH_NO_ERROR;
-err:
-       return FRSH_ERR_INTERNAL_ERROR;
-}
-
-/*
- * frsh_thread_unbind(), unbind a thread from a vres
- *
- * possible return values:
- *  FRSH_NO_ERROR
- *  FRSH_ERR_NOT_INITIALIZED
- *  FRSH_BAD_ARGUMENT(*) (invalid thread)
- *  FRSH_ERR_NOT_BOUND(*)
- *  FRSH_ERR_INTERNAL_ERROR(*) (something wrong with AQuoSA or with the service thread internal data structures)
- */
-int frsh_thread_unbind(const frsh_thread_id_t thread)
-{
-       int ret;
-       /* TODO: solve thread -> vres mapping */
-#if 0
-       char path[FILENAME_MAX];
-       struct cgroup* cgroup = (struct cgroup*)vres->priv;
-       FILE* taskf;
-
-       /*if (!aqcpu_is_initialized) {
-                 return(FRSH_ERR_NOT_INITIALIZED);
-       }*/
-       
-       if (!cg_build_path(cgroup->name, path, cgroup->controller[i]->name)){
-               return FRSH_ERR_INTERNAL_ERROR;
-       }
-       
-       strcat(path, "tasks");
-       taskf = fopen(path, "w");
-       if (!taskf) {
-               return FRSH_ERR_INTERNAL_ERROR;
-       }
-       fclose(taskf);
-#endif
-
-       ret = fra_delete_thread_vres(&thread);
-       if (ret) goto err;
-
-       return FRSH_NO_ERROR;
-err:
-       return FRSH_ERR_INTERNAL_ERROR;
-}
-
-/**
- * Wrapper thread
- * 
- * possible exit status:
- *  FRSH_ERR_INTENRAL_ERROR (something wrong with threads and signal handling)
- *  FRSH_ERR_TOO_MANY_TASKS(*)
- *  FRSH_ERR_BAD_ARGUMENT(*) (invalid vres)
- *  FRSH_ERR_NOT_CONTRACTED_VRES(*)
- *  whatever the user provided code 'pthread_code' returns
- */
-static void* wrapper_pthread(void *arg)
-{
-       wrapper_pthread_arg_t* pth = (wrapper_pthread_arg_t*) arg;      
-       frsh_thread_id_t* thread_id = pth->thread_id;   
-       void *thread_arg = pth->pthread_arg;
-       frsh_thread_code_t thread_code = pth->pthread_code;
-       int  errcode;
-       
-       *thread_id = fosa_thread_self();
-       /* bind this thread to vres */
-       errcode = frsh_thread_bind(pth->vres, *thread_id);
-       pth->errcode = errcode;
-
-       sem_post(pth->stopper);
-       /* No access to pth is allowed after this point, it can vanish already */
-
-       if (errcode) /* vres binding was not successful */
-               return NULL;
-
-       /* execute thread function */   
-       return thread_code(thread_arg);
-}
-
-/*
- * frsh_thread_bind(), create a new thread and bind it to a vres
- * frsh_thread_create_in_background(), create a new thread and a new BACKGROUND contract 
- * and bind them
- *
- * The two functions both create a new thread and bind it to a vres, existing
- * fr the former, created for the latter.
- *
- * The implementation uses a wrapper function as the new thread code (it's
- * the simplest way to handle some issues on POSIX 'pthread_t' and
- * 'pthread_self()', for a detailed explanation of the "problem" ask the
- * authors via e-mail) which, on its turn, bind itself to the vres and then
- * run the user provided code. The API calls simply create the new thread,
- * using the wrapper thread code, and return.
- *
- * Note that in order to return the caller the descriptor of the new created
- * thread (known to the wrapped thread but not entirely to the API calls) a
- * special 'struct' data type is passed as the parameter of the wrapper thread
- * and a simple synchronization mechanism based on semaphore is realized.
- *
- * possible return values:
- *  see below the comments of each specific API call
- */
-
-/*
- * API call for 'frsh_thread_create_and_bind()', as said prepares the
- * wrapper code argument data structure, create the new thread and wait
- * its acknowledgment before stepping over
- *
- * possible return values:
- *  FRSH_NO_ERROR
- *  FRSH_ERR_NOT_INITIALIZED
- *  FRSH_ERR_BAD_ARGUMENT (NULL thread or thread_code)
- *  whatever 'fosa_thread_create()' returns
- *  FRSH_ERR_INTERNAL_ERROR 
- */
-int frsh_thread_create_and_bind(const frsh_vres_id_t vres,
-       frsh_thread_id_t *thread,
-       frsh_thread_attr_t *thread_attr,
-       frsh_thread_code_t thread_code,
-       void *arg)
-{
-       wrapper_pthread_arg_t wp;
-       int rv;
-       sem_t stopper;
-       struct sched_param param;
-       int p = 0;
-       frsh_thread_attr_t updated_attr;
-
-       sem_init(&stopper, 0, 0);
-       
-       if (!thread || !thread_code || !thread_attr)
-               return FRSH_ERR_BAD_ARGUMENT;
-
-       wp.parent_thread_id = fosa_thread_self();
-       wp.thread_id = thread;  
-       wp.pthread_code = thread_code;
-       wp.pthread_arg = arg;   
-       wp.vres = vres;
-       wp.stopper = &stopper;
-
-       pthread_attr_getschedparam(thread_attr, &param);
-       p = param.sched_priority;
-       printf("priority = %d\n", p);
-       if (p == 0) {
-               updated_attr = *thread_attr;
-               param.sched_priority = 1;
-               pthread_attr_setschedparam(&updated_attr, &param);
-               pthread_attr_getschedparam(&updated_attr, &param);
-               printf("changed priority = %d\n", param.sched_priority);
-               pthread_attr_setinheritsched(&updated_attr, PTHREAD_EXPLICIT_SCHED);
-               pthread_attr_setschedpolicy(&updated_attr, SCHED_RR);
-               pthread_attr_setscope(&updated_attr, PTHREAD_SCOPE_SYSTEM);
-               thread_attr = &updated_attr; 
-       }
-       
-       /* create the wrapper thread */ 
-       rv = fosa_thread_create(thread, thread_attr, wrapper_pthread, (void*)&wp);
-       if (rv != 0)
-               return(rv);
-       
-       sem_wait(&stopper);
-       return (wp.errcode);
-}
-
-int frsh_vres_get_usage
-  (const frsh_vres_id_t vres,
-   frsh_rel_time_t *spent)
-{
-       return FRSH_ERR_NOT_IMPLEMENTED;
-}
-
-int frsh_vres_get_job_usage
-  (const frsh_vres_id_t vres,
-   frsh_rel_time_t *spent)
-{
-       return FRSH_ERR_NOT_IMPLEMENTED;
-}
-
-int frsh_vres_get_remaining_budget
-  (const frsh_vres_id_t vres,
-   frsh_rel_time_t *budget)
-{
-       return FRSH_ERR_NOT_IMPLEMENTED;
-}
-
-int frsh_feedback_get_spare
-  (frsh_contract_t *spare_contract)
-{
-       return FRSH_ERR_NOT_IMPLEMENTED;
-}
-
-int frsh_feedback_set_spare
-  (const frsh_contract_t *spare_contract)
-{
-       return FRSH_ERR_NOT_IMPLEMENTED;
-}
-
-int frsh_feedback_get_desired_budget
-  (frsh_vres_id_t vres_id,
-   frsh_rel_time_t *p_budget_out)
-{
-       return FRSH_ERR_NOT_IMPLEMENTED;
-}
-
-int frsh_feedback_set_desired_budget
-  (frsh_vres_id_t vres_id,
-   frsh_rel_time_t *p_budget_in)
-{
-       return FRSH_ERR_NOT_IMPLEMENTED;
-}
-
-int frsh_feedback_get_actual_budget
-  (frsh_vres_id_t vres_id,
-   frsh_rel_time_t *budget)
-{
-       return FRSH_ERR_NOT_IMPLEMENTED;
-}
-