]> rtime.felk.cvut.cz Git - frescor/fwp.git/commitdiff
Clean up. frsh_aquosa/scheduler.c -> frsh_aquosa/cpu_sched.c, removed frsh_aquosa...
authorMartin <molnar@sum.(none)>
Fri, 19 Sep 2008 10:00:52 +0000 (12:00 +0200)
committerMartin <molnar@sum.(none)>
Fri, 19 Sep 2008 10:00:52 +0000 (12:00 +0200)
frsh_aquosa/Makefile.omk
frsh_aquosa/cpu_sched.c [moved from frsh_aquosa/scheduler.c with 98% similarity]
frsh_aquosa/synchobj.c [deleted file]

index 5b865ba5efe2b43adbf996a51d112c2bf9baad11..7dacc6e3fa8a856a16223c5fbb2b2b24a5a878a0 100644 (file)
@@ -1,6 +1,8 @@
 lib_LIBRARIES = frsh_aquosa
 SUBDIRS = aquosa
 frsh_aquosa_SOURCES += core.c cpu_contract.c 
-include_HEADERS= cpu_contract.h
+include_HEADERS += cpu_contract.h 
+include_HEADERS +=$(wildcard aquosa/qresmod/*.h)
+include_HEADERS +=$(wildcard aquosa/rresmod/*.h)
 
 lib_LOADLIBES+= frsh
similarity index 98%
rename from frsh_aquosa/scheduler.c
rename to frsh_aquosa/cpu_sched.c
index 5f9b5eff78b36eb408ec1463c21a0cc6ee950de0..823ae64ff05df8b5fb84ac8563964774254679fe 100644 (file)
@@ -97,7 +97,7 @@ int cpu_sched_exit()
 }
 
 #if 0
-frsh_sched_ops cpu_sched_ops = {
+sched_ops cpu_sched_ops = {
        .init = aquosa_init();
        .exit = aquosa_exit();
        .create_vres = aquosa_create_vres();
diff --git a/frsh_aquosa/synchobj.c b/frsh_aquosa/synchobj.c
deleted file mode 100644 (file)
index bff5edc..0000000
+++ /dev/null
@@ -1,729 +0,0 @@
-
-//synchobj_repo_t synchobj_repo;       /* defined downward, after the type definition! */
-
-/*
- * synchronization objects repository
- *
- * data structure and macro declaration for the handling of the repository
- * of synchronization objects needed by the API implementation.
- * It's used only in the core API module so no problem implementing it all
- * in this file without affecting the header files in frsh/include with
- * such an implementation specific and tighted issue
- *
- * Note that mutual exclusive access is implemented both for the repository
- * as a whole and for each single element to maximize the achievable
- * parallelism and concurrency execution of threads
- *
- * Note also the synchronization object (subsection of the core) API is
- * implemented within this file, without any request to the service thread,
- * and so all "remain" local to a single process!
- */
-
-/* data structures */
-
-typedef struct synchobj_repo_entry {
-       frsh_mutex_t mutex;
-       fosa_cond_t sync;
-       int events;
-       int queued;
-} synchobj_repo_entry_t;
-
-typedef struct synchobj_repo {
-       synchobj_repo_entry_t repo[FRSH_MAX_N_SYNCH_OBJECTS];
-       int synchobj_number;
-       frsh_mutex_t mutex;
-} synchobj_repo_t;
-
-synchobj_repo_t synchobj_repo; /* global variable */
-
-/* macro and functions */
-
-/*
- * access functions to the repository
- *
- * some simple macro which help keep synchobj_repo_t opaque
- * for the sake of code cleanness
- */
-
-/* given the handle of a synchronization object returns its index into the
- * repository (frsh_synchobj_handle_t remains opaque) */
-#define synchobj_handle_2_ind(h) \
- ( h )
-/* given the index of a synchronization object in the repository returns
- * an handle to it (frsh_synchobj_handle_t remains opaque)*/
-#define synchobj_ind_2_handle(i) \
- ( i )
-/* given a handle of a synchronization object returns a pointer to
- * its entry into the repository */
-#define get_synchobj_entry(handle) \
-( & ( synchobj_repo.repo[synchobj_handle_2_ind(handle)] ) )
-/* return a pointer to the synchronization object repository mutex */
-#define get_synchobj_repo_mutex() \
- ( & ( synchobj_repo.mutex ) )
-/* gives the actual number of synchronization objects in the repository */
-#define get_synchobj_number() \
- ( synchobj_repo.synchobj_number )
-
-/*
- * consistency and status checks
- *
- * common used checkings and tests about the access to the repository
- * and the status of each entry
- */
-
-/* are we accessing the repository with a valid index value ? */
-#define check_synchobj_repo_ind(ind) \
- ( ( ind >= 0 && ind < FRSH_MAX_N_SYNCH_OBJECTS ) ? true: false )
-/* is the repository entry (correctly accessed and) free ? */
-#define check_synchobj_repo_entry_free(ind)                    \
- ( ( (check_synchobj_repo_ind(ind)) &&                         \
-  synchobj_repo.repo[ind].events == -1 ) ? true : false )
-/* is the repository entry (correctly accessed and) non free ? */
-#define check_synchobj_repo_entry_nonfree(ind)                 \
- ( ( (check_synchobj_repo_ind(ind)) &&                         \
-  synchobj_repo.repo[ind].events != -1 ) ? true : false )
-
-/*
- * initialize the repository
- *
- * sets all entries to invalid (that is, free) and init
- * the "global" mutexe
- *
- * possible return values:
- *  true (all ok)
- *  false (something wrong with the mutex)
- */
-static inline bool synchobj_repo_init()
-{
-       int i;
-
-       if (fosa_mutex_init(&synchobj_repo.mutex, 0) != 0)
-               return false;
-
-       synchobj_repo.synchobj_number = 0;
-       for (i = 0; i < FRSH_MAX_N_SYNCH_OBJECTS; i++) {
-               synchobj_repo.repo[i].events = -1;
-               synchobj_repo.repo[i].queued = -1;
-       }
-
-       return true;
-}
-
-/*
- * add an entry
- *
- * adds an entry into the repository. If successful the index of the entry is
- * returned in vres_ind.
- *
- * We suppose the caller where to place the new entry and "suggests" us a
- * free repository entry in synchobj_ind. We then check if it's really free
- * and, if yes, we add the entry right there.
- * If, on the other way, the entry is not free we need to search the whole
- * repository for a suitable place.
- *
- * possible return values:
- *  true (entry correctly added)
- *  false (entry not added, maybe no more room in the repository!)
- */
-static inline bool synchobj_repo_put(int *synchobj_ind)
-{
-
-       int i;
-       bool result;
-
-       /* lock the repository */
-       fosa_mutex_lock(&synchobj_repo.mutex);
-       /* try to place the new entry in the caller provided position (if any)
-        * and, only if it's not free, scan all the repository for
-        * a different and suitable place */
-       if (synchobj_ind != NULL &&
-                       check_synchobj_repo_entry_free(*synchobj_ind % FRSH_MAX_N_SYNCH_OBJECTS))
-               i = *synchobj_ind % FRSH_MAX_N_SYNCH_OBJECTS;
-       else {
-               i = 0;
-               while (i < FRSH_MAX_N_SYNCH_OBJECTS && !check_synchobj_repo_entry_free(i))
-                       i++;
-       }
-       /* if we're sure it's valid and free we place the
-        * thread entry into the repository in position 'i' */
-       result = false;
-       if (check_synchobj_repo_entry_free(i)) {
-               if (fosa_mutex_init(&synchobj_repo.repo[i].mutex, 0) != 0)
-                       return false;
-               if (fosa_cond_init(&synchobj_repo.repo[i].sync) != 0)
-                       return false;
-               synchobj_repo.repo[i].events = 0;
-               synchobj_repo.repo[i].queued = 0;
-               if (synchobj_ind != NULL)
-                       *synchobj_ind = i;
-               result = true;
-       }
-
-       /* unlock the repository */
-       fosa_mutex_unlock(&synchobj_repo.mutex);
-
-       return result;
-}
-
-/*
- * remove an entry
- *
- * sets the entry as free (if it already is not) and decrement the counter
- *
- * possible return values:
- *  true (all ok, entry was non-free and is now free)
- *  false (something wrong, entry was already free or index is out of renge)
- */
-static inline bool synchobj_repo_free(const int synchobj_ind)
-{
-       bool result;
-
-       /* lock the whole repository */
-       fosa_mutex_lock(&synchobj_repo.mutex);
-
-       result = false;
-       if (check_synchobj_repo_entry_nonfree(synchobj_ind)) {
-               fosa_mutex_destroy(&synchobj_repo.repo[synchobj_ind].mutex);
-               fosa_cond_destroy(&synchobj_repo.repo[synchobj_ind].sync);
-               synchobj_repo.repo[synchobj_ind].events = -1;
-               synchobj_repo.repo[synchobj_ind].queued = -1;
-               synchobj_repo.synchobj_number--;
-               result = true;
-       }
-
-       /* unlock the whole repository */
-       fosa_mutex_unlock(&synchobj_repo.mutex);
-
-       return result;
-}
-
-/*
- * is an entry free ?
- *
- * check if a specific entry of the repository can be considered free
- * (we need do it with an atomic lock)
- *
- * possible return values:
- *  true (entry is free)
- *  false (entry is not free or index is out of range)
- */
-static inline bool synchobj_repo_isfree(const int synchobj_ind)
-{
-       bool result;
-
-       /* lock the repository */
-       fosa_mutex_lock(&synchobj_repo.mutex);
-
-       result = check_synchobj_repo_entry_free(synchobj_ind);
-
-       /* unlock the repository */
-       fosa_mutex_unlock(&synchobj_repo.mutex);
-
-       return result;
-}
-
-/////////////////////////////////////////////////
-// S Y N C H R O N I Z A T I O N   O B J E C T S
-/////////////////////////////////////////////////
-
-/*
- * This section is implemented much differently from how it's described
- * in the docs since the synchronization object are not unusable from
- * INDETERMINATE workload type thread (remember we actually we're
- * only handling such a type of vres!!), but they simply provide, for them,
- * a conditional [timed] wait/signal mechanism as available and implemented in
- * many OSs and threading library.
- *
- * In INDETERMINATE workloads, of course, a wait request on an synchronization
- * object (or a timed wait request) does not imply the end of the current job
- * nor cause any budget to be "returned", since no jobs are defined for them.
- *
- * In BUONDED workloads, when they'll be implemented here, we can flawlessy
- * realize the API docs' semantic and consider end-job signals and budget
- * return
- *
- * Note that, beside the peculiarity of this implementation being the
- * orthogonality with respect to threads and processes, all the
- * synchronization objects API section is implemented without bothering the
- * service thread, so it remains local to the single process and usable from
- * its various threads to synchronize themself, i.e. it is by no way usable in
- * order to synchronize different processes or different threads among
- * different processes between each other!
- */
-
-/*
- * frsh_synchobj_create(), create a synchronization object
- *
- * Note FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD and
- * FRSH_ERR_INVALID_SCHEDULER_REPLY are never returned as errors within
- * this implementation
- *
- * possible return values:
- *  FRSH_NO_ERROR
- *  FRSH_ERR_NOT_INITIALIZED
- *  FRSH_ERR_BAD_ARGUMENT (NULL synchronization object handle)
- *  FRSH_ERR_TOO_MANY_SYNCH_OBJECTS
- *  FRSH_ERR_INTERNAL_ERROR (something, different from previous, went wrong)
- */
-int frsh_synchobj_create(frsh_synchobj_handle_t *synch_handle)
-{
-       int synch_ind;
-
-#ifdef DEBUG
-       strncpy(FUNCNAME, "frsh_synchobj_create", 21);
-#endif
-
-       /* 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 (synch_handle == NULL)
-               PERROR_AND_RETURN(FRSH_ERR_BAD_ARGUMENT,
-                               "can't return a synchronization object in a NULL synch_handle");
-
-       /* add the object and return an handler to it */
-       if (synchobj_repo_put(&synch_ind))
-               *synch_handle = synchobj_ind_2_handle(synch_ind);
-       else
-               /* something wrong, try to guess what */
-               if (get_synchobj_number() >= FRSH_MAX_N_SYNCH_OBJECTS)
-                       /* synchronization object max number reached */
-                       PERROR_AND_RETURN(FRSH_ERR_TOO_MANY_SYNCH_OBJS,
-                                       "can't create any more synchronization objects");
-               else
-                       /* unspecified error (this should almost never be reached) */
-                       PERROR_AND_RETURN(FRSH_ERR_INTERNAL_ERROR,
-                                       "can't create the synchronization objects");
-
-       return FRSH_NO_ERROR;
-}
-
-/*
- * frsh_synchobj_destroy(), destroy a synchronization object
- *
- * Note we check if wakeing up some threads is needed and we do this while
- * holding a lock on the synchronization object, acquired while holding
- * a lock on the whole repository in order to prevent races
- *
- * Note FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD and
- * FRSH_ERR_INVALID_SCHEDULER_REPLY are never returned as errors within
- * this implementation too
- *
- * possible return value:
- *  FRSH_NO_ERROR
- *  FRSH_ERR_NOT_INITIALIZED
- *  FRSH_ERR_INVALID_SYNCH_OBJ_HANDLE
- *  FRSH_ERR_INTERNAL_ERROR (something, different from previous, went wrong)
- */
-int frsh_synchobj_destroy(const frsh_synchobj_handle_t synch_handle)
-{
-       /* 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 (synchobj_repo_isfree(synchobj_handle_2_ind(synch_handle)))
-               PERROR_AND_RETURN(FRSH_ERR_INVALID_SYNCH_OBJ_HANDLE,
-                               "can't destroy a synchronization object from an invalid synch_handle");
-
-       /* get an exclusive access lock to the synchronization object
-        * while holding the exclusive access to the whole repository for the
-        * sake of safetyness */
-       fosa_mutex_lock(get_synchobj_repo_mutex());
-       fosa_mutex_lock(&(get_synchobj_entry(synch_handle)->mutex));
-       fosa_mutex_unlock(get_synchobj_repo_mutex());
-       /* have I got to wake up someone ?? */
-       while (get_synchobj_entry(synch_handle)->queued > 0) {
-               if (fosa_cond_signal(&(get_synchobj_entry(synch_handle)->sync)) != 0) {
-                       fosa_mutex_unlock(&(get_synchobj_entry(synch_handle)->mutex));
-                       fosa_mutex_unlock(get_synchobj_repo_mutex());
-                       PERROR_AND_RETURN(FRSH_ERR_INTERNAL_ERROR,
-                                       "can't wake up blocked threads while destroying the synchronization object");
-               } else
-                       get_synchobj_entry(synch_handle)->queued--;
-       }
-       /* release the lock on the synchronization object */
-       fosa_mutex_unlock(&(get_synchobj_entry(synch_handle)->mutex));
-
-       /* remove the synchronization object from the repository */
-       if (!synchobj_repo_free(synchobj_handle_2_ind(synch_handle)))
-               /* unspecified error (this should almost never be reached) */
-               PERROR_AND_RETURN(FRSH_ERR_INTERNAL_ERROR,
-                               "can't delete the synchronization objects");
-
-       return FRSH_NO_ERROR;
-}
-
-/*
- * frsh_synchobj_wait() and frsh_synchobj_wit_with_timeout
- *
- * They're very very much similar between each other so we choose to implement
- * them using a single generic function with a few more parameters to
- * discriminate the two behaviours, avoiding a lot of code replication
- */
-
-static int synchobj_wait(bool with_timeoout,           /* forward declaration of the generic wait function */
-       const frsh_synchobj_handle_t synch_handle,
-       const struct timespec *abs_timeout,
-       bool *timed_out,
-       struct timespec *next_budget,
-       struct timespec *next_period,
-       bool *was_deadline_missed,
-       bool *was_budget_overran);
-
-/*
- * frsh_synchobj_wait(), stop the thread till signaled by another one
- *
- * Implements the standard behaviour of a wait for a condition to be verified
- * and signaled by another thread of the process.
- *
- * As stated before is perfectly usable even by the INDETERMINATE workloads
- * for whom it does not represent the 'end job' event.
- *
- * It's implemented simply by a call to the generic function coded below
- *
- * Note FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD and
- * FRSH_ERR_INVALID_SCHEDULER_REPLY are never returned as errors within
- * this implementation and also FRSH_ERR_WORKLOAD_NOT_COMPATIBLE
- * is ignored by us
- *
- * possible return values:
- *  FRSH_NO_ERROR
- *  FRSH_ERR_NOT_INITIALIZED
- *  FRSH_ERR_INVALID_SYNCH_OBJ_HANDLE (invalid synch. object or too many thread queued on it)
- *  all that frsh_thread_get_vres_id returns (FRSH_ERR_NOT_BOUND, )
- *  FRSH_ERR_INTERNAL_ERROR (something wrong trying to wait on the object)
- */
-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_overran)
-{
-       /* simply call the generic function asking for a wait without any timeout */
-       return synchobj_wait(false, synch_handle, NULL, NULL, next_budget, next_period,
-                       was_deadline_missed, was_budget_overran);
-}
-
-/*
- * frsh_synchobj_wait_with_timeout(), stop the thread till a timeout or a signal by another one
- *
- * Implements the standard behaviour of a wait for a condition to be verified
- * and signaled by another thread of the process with a max. timeout value
- *
- * It's exactly the same as 'frsh_synchobj_wait()' with the only difference of
- * the timeout and so it's, again, implemented simply by a call to the generic
- * function with the correct parameters
- *
- * Note FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD and
- * FRSH_ERR_INVALID_SCHEDULER_REPLY are never returned as errors within
- * this implementation and also FRSH_ERR_WORKLOAD_NOT_COMPATIBLE
- * is ignored by us
- *
- * possible return values:
- *  FRSH_NO_ERROR
- *  FRSH_ERR_NOT_INITIALIZED
- *  FRSH_ERR_INVALID_SYNCH_OBJ_HANDLE (invalid synch. object or too many thread queued on it)
- *  all that 'frsh_thread_get_vres_id()' returns (FRSH_ERR_NOT_BOUND, )
- *  FRSH_ERR_INTERNAL_ERROR (something wrong trying to wait on the object)
- */
-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)
-{
-       /* simply call the generic function asking for a wait with the specified timeout */
-       return synchobj_wait(true, synch_handle, abs_timeout, timed_out, next_budget, next_period,
-                       was_deadline_missed, was_budget_overran);
-}
-
-/*
- * generic function definition:
- *  it _really_ implements both (depending on the parameters)
- *  wait on synchronization objects API calls
- */
-static int synchobj_wait(bool with_timeout,    /* discriminating parameter between the two functions */
-       const frsh_synchobj_handle_t synch_handle,
-       const struct timespec *abs_timeout,
-       bool *timed_out,
-       struct timespec *next_budget,
-       struct timespec *next_period,
-       bool *was_deadline_missed,
-       bool *was_budget_overran)
-{
-       frsh_thread_id_t thread_self;
-       qres_sid_t thread_sid;
-       qres_time_t qres_thread_budget;
-       struct timespec tmp_thread_budget, tmp_thread_period;
-       frsh_vres_id_t vres_id;
-       int frsh_status, timedwait_status;
-
-       /* 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()'!");
-       /* check the thread is running with a negotiated contract */
-       thread_self = fosa_thread_self();
-       thread_sid = FRSH_QRES_NOT_VALID_SID;
-       vres_id = FRSH_NOT_VALID_VRES_ID;
-       /* ask AQuoSA directly, if it's succesfull we can avoid a call to
-        * the service thread that is much less overhead!! */
-       if (qres_get_sid(thread_self.linux_pid, thread_self.linux_tid, &thread_sid) == QOS_E_NOSERVER)
-               /* maybe we're bounded to a background vres and, in order
-                * of being sure, we need to ask the service thread :-( */
-               if ( (frsh_status = frsh_thread_get_vres_id(thread_self, &vres_id)) != FRSH_NO_ERROR)
-                       PERROR_AND_RETURN(frsh_status,
-                                       "can't wait if the thread is not bound to any vres");
-       if (synchobj_repo_isfree(synchobj_handle_2_ind(synch_handle)))
-               PERROR_AND_RETURN(FRSH_ERR_INVALID_SYNCH_OBJ_HANDLE,
-                               "can't wait on an synchronization object via an invalid synch_handler");
-
-       /* acquire the exclusive access lock on the synchronization object
-        * while holding it on the whole repository */
-       fosa_mutex_lock(get_synchobj_repo_mutex());
-       fosa_mutex_lock(&(get_synchobj_entry(synch_handle)->mutex));
-       fosa_mutex_unlock(get_synchobj_repo_mutex());
-
-       /* check if we can wait on the object or the limit has already been reached */
-       if ((get_synchobj_entry(synch_handle)->events == 0) &&
-                       (get_synchobj_entry(synch_handle)->queued >= FRSH_MAX_N_VRES_IN_SYNCH_OBJECT)) {
-               fosa_mutex_unlock(&(get_synchobj_entry(synch_handle)->mutex));
-               PERROR_AND_RETURN(FRSH_ERR_INVALID_SYNCH_OBJ_HANDLE,
-                               "can't queue more vres on this synchronization object");
-       }
-       /* we need to wait only if there are no ready events */
-       if (!get_synchobj_entry(synch_handle)->events) {
-               /* inform we're going to suspend oursef! */
-               get_synchobj_entry(synch_handle)->queued++;
-               if (with_timeout) {
-                       *timed_out = false;
-                       timedwait_status = fosa_cond_timedwait(&(get_synchobj_entry(synch_handle)->sync),
-                                       &(get_synchobj_entry(synch_handle)->mutex),
-                                       abs_timeout);
-                       if (timedwait_status != 0) {
-                               if (timedwait_status == ETIMEDOUT) {
-                                       /* no signal event before the timeout */
-                                       *timed_out = true;
-                                       get_synchobj_entry(synch_handle)->events++;     /* preventive increment */
-                               } else {
-                                       /* some other strange error! */
-                                       fosa_mutex_unlock(&(get_synchobj_entry(synch_handle)->mutex));
-                                       PERROR_AND_RETURN(FRSH_ERR_INTERNAL_ERROR,
-                                               "can't wait on the synchronization object");
-                               }
-                       }
-               } else
-                       if (fosa_cond_wait(&(get_synchobj_entry(synch_handle)->sync),
-                                       &(get_synchobj_entry(synch_handle)->mutex)) != 0) {
-                               fosa_mutex_unlock(&(get_synchobj_entry(synch_handle)->mutex));
-                               PERROR_AND_RETURN(FRSH_ERR_INTERNAL_ERROR,
-                                               "can't wait on the syncrhonization object");
-                       }
-               /* the synchronization object is still valid? */
-               if (synchobj_repo_isfree(synchobj_handle_2_ind(synch_handle)))
-                       /* no, someone destroyed our synchronization object! */
-                       PERROR_AND_RETURN(FRSH_ERR_INVALID_SYNCH_OBJ_HANDLE,
-                                       "synchronization object no longer valid, it has been destroyed during wait");
-               get_synchobj_entry(synch_handle)->queued--;
-       }
-       get_synchobj_entry(synch_handle)->events--;
-       /* all done, release the lock on the synchronization object */
-       fosa_mutex_unlock(&(get_synchobj_entry(synch_handle)->mutex));
-
-       /* now retreive timing (budget and period) parameters, don't care about
-        * overruns (remember we're always WT_INDETERMINATE) and make them 
-        * both 'false' */
-       if (next_period != NULL || (next_budget != NULL && thread_sid == -1)) {
-               /* ask the service thread only if it's strictly necessary !! */
-               if (vres_id == FRSH_NOT_VALID_VRES_ID)
-                       /* we need to know (from the service thread) the vres_id */
-                       if ( (frsh_status = frsh_thread_get_vres_id(thread_self, &vres_id)) != FRSH_NO_ERROR)
-                               PERROR_AND_RETURN(frsh_status,
-                                               "can't gather vres info for period and budget retrieval");
-               if (frsh_vres_get_budget_and_period(vres_id,
-                       &tmp_thread_budget,
-                       &tmp_thread_period) != FRSH_NO_ERROR)
-                       PERROR_AND_RETURN(FRSH_ERR_INTERNAL_ERROR,
-                                       "can't get vres/contract budget and period");
-       }
-       if (next_budget != NULL) {
-               if (thread_sid == FRSH_QRES_NOT_VALID_SID)
-                       /* background thread, we use the contracted budget
-                        * retrieved previously */
-                       *next_budget = tmp_thread_budget;
-               else {
-                       /* regular thread, ask for the actual budget direclty to AQuoSA
-                        * (much less overhead !!) */
-                       if (qres_get_curr_budget(thread_sid, &qres_thread_budget) != QOS_OK)
-                               PERROR_AND_RETURN(FRSH_ERR_INTERNAL_ERROR,
-                                               "can't get the actual budget for the vres");
-                       usec_to_timespec(*next_budget, qres_thread_budget);
-               }
-       }
-       if (next_period != NULL)
-               *next_period = tmp_thread_period;
-       if (was_deadline_missed != NULL)
-               was_deadline_missed = false;
-       if (was_budget_overran != NULL)
-               was_budget_overran = false;
-
-       return FRSH_NO_ERROR;
-}
-
-/*
- * frsh_synchobj_signal(), notify a synchronization object
- *
- * Remember if noone is waiting for the notification it is queued in the
- * synchronization objects
- *
- * Note FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD and
- * FRSH_ERR_INVALID_SCHEDULER_REPLY are never returned as errors within
- * this implementation too
- *
- * possible return values:
- *  FRSH_NO_ERROR
- *  FRSH_ERR_NOT_INITIALIZED
- *  FRSH_ERR_BAD_ARGUMENT (invalid synch_handle)
- *  FRSH_ERR_TOO_MANY_EVENTS_IN_SYNCH_OBJ
- */
-int frsh_synchobj_signal(const frsh_synchobj_handle_t synch_handle)
-{
-       /* 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 (synchobj_repo_isfree(synchobj_handle_2_ind(synch_handle)))
-               PERROR_AND_RETURN(FRSH_ERR_BAD_ARGUMENT,
-                               "can't signal a synchronization object via an invalid synch_handle");
-       /* acquire the exclusive access lock on the synchronization object
-        * while holding it on the whole repository */
-       fosa_mutex_lock(get_synchobj_repo_mutex());
-       fosa_mutex_lock(&(get_synchobj_entry(synch_handle)->mutex));
-       fosa_mutex_unlock(get_synchobj_repo_mutex());
-
-       if (get_synchobj_entry(synch_handle)->events >= FRSH_MAX_N_EVENTS_IN_SYNCH_OBJECT) {
-               fosa_mutex_unlock(&(get_synchobj_entry(synch_handle)->mutex));
-               PERROR_AND_RETURN(FRSH_ERR_TOO_MANY_EVENTS_IN_SYNCH_OBJ,
-                               "can't enqueue more events on the synchronization object");
-       }
-       get_synchobj_entry(synch_handle)->events++;
-
-       /* release the lock */
-       fosa_mutex_unlock(&(get_synchobj_entry(synch_handle)->mutex));
-       /* and, finally, signal the condition */
-       fosa_cond_signal(&(get_synchobj_entry(synch_handle)->sync));
-       
-       return FRSH_NO_ERROR;
-}
-
-/*
- * frsh_timed_wait(), sleep until specified absolute time
- *
- * Again, it does not imply 'end job' or any budget modification for
- * INDETERMINATE workload vres, simply wait for the timer to fire!
- *
- * The timeout is implemented via the 'clock_nanosleep()' function
- * (we need to consider a fosa wrapper for it too) in order to get rid
- * of all the problems related to signal handling in a multithreaded
- * environment (and even because it's the simplest and best suited
- * solution for the acheiving what we need to!!)
- *
- * possible return values:
- *  FRSH_NO_ERROR
- *  FRSH_ERR_NOT_INITIALIZED
- *  FRSH_ERR_BAD_ARGUMENT (NULL abs_time)
- *  FRSH_ERR_INTERNAL_ERROR (FRSH_ERR_TIME_SPEC_IN_THE_PAST)
- *  FRSH_ERR_INTERNAL_ERROR (something wrong with timer and/or signal handling)
- *  all that 'frsh_thread_get_vres_id()' returns (FRSH_ERR_NOT_BOUND, )
- */
-
-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)
-{
-       frsh_thread_id_t thread_self;
-       qres_sid_t thread_sid;
-       qres_time_t qres_thread_budget;
-       struct timespec tmp_thread_budget, tmp_thread_period;
-       frsh_vres_id_t vres_id;
-       frsh_abs_time_t actual_time, rm_time;
-       int frsh_status;
-
-       /* 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 (abs_time == NULL)
-               PERROR_AND_RETURN(FRSH_ERR_BAD_ARGUMENT,
-                               "can't wait for a NULL abs_time");
-       /* check the thread is running with a negotiated contract */
-       thread_self = fosa_thread_self();
-       thread_sid = FRSH_QRES_NOT_VALID_SID;
-       vres_id = FRSH_NOT_VALID_VRES_ID;
-       if (qres_get_sid(thread_self.linux_pid, thread_self.linux_tid, &thread_sid) == QOS_E_NOSERVER)
-               /* maybe we're bounded to a background vres and, in order
-                * of being sure, we need to ask the service thread :-( */
-               if ( (frsh_status = frsh_thread_get_vres_id(thread_self, &vres_id)) != FRSH_NO_ERROR)
-                       PERROR_AND_RETURN(frsh_status,
-                                       "can't get the vres id the calling thread is associated with");
-       /* check the provided absolute time reference is in the future */
-       if (fosa_clock_get_time(FOSA_CLOCK_REALTIME, &actual_time) < 0)
-               PERROR_AND_RETURN(FRSH_ERR_INTERNAL_ERROR,
-                               "can't get the current time");
-       if (frsh_abs_time_smaller(*abs_time, actual_time))
-               //PERROR_AND_RETURN(FRSH_ERR_TIME_SPEC_IN_THE_PAST,
-               PERROR_AND_RETURN(FRSH_ERR_INTERNAL_ERROR,
-                               "can't wait for a past absolute time");
-       /* put the thread to sleep for the requested interval */
-       if (clock_nanosleep(FOSA_CLOCK_REALTIME, TIMER_ABSTIME, abs_time, &rm_time) < 0)
-               PERROR_AND_RETURN(FRSH_ERR_INTERNAL_ERROR,
-                               "can't put the thread to sleep");
-       /* if ( <check, via rm_time, if we've been interrupted> )
-        *      ... ... ...
-        *      ... ... ... */
-       /* retreive timing (budget and period) parameters, don't care about
-        * overruns (remember we're always WT_INDETERMINATE) and make them 
-        * both 'false' */
-       if (next_period != NULL || (next_budget != NULL && thread_sid == FRSH_QRES_NOT_VALID_SID)) {
-               /* ask the service thread only if it's strictly necessary !! */
-               if (vres_id == FRSH_NOT_VALID_VRES_ID)
-                       /* we need to know (from the service thread) the vres_id !! */
-                       if ( (frsh_status = frsh_thread_get_vres_id(thread_self, &vres_id)) != FRSH_NO_ERROR)
-                               PERROR_AND_RETURN(frsh_status,
-                                               "can't gather vres info for period and budget retrieval");
-               if (frsh_vres_get_budget_and_period(vres_id,
-                       &tmp_thread_budget,
-                       &tmp_thread_period) != FRSH_NO_ERROR)
-                       PERROR_AND_RETURN(FRSH_ERR_INTERNAL_ERROR,
-                                       "can't get vres/contract budget and period");
-       }
-       if (next_budget != NULL) {
-               if (thread_sid == FRSH_QRES_NOT_VALID_SID)
-                       /* background thread, we use the contracted budget
-                        * retrieved previously */
-                       *next_budget = tmp_thread_budget;
-               else {
-                       /* regular thread, ask for the actual budget direclty to AQuoSA
-                        * (much less overhead !!) */
-                       if (qres_get_curr_budget(thread_sid, &qres_thread_budget) != QOS_OK)
-                               PERROR_AND_RETURN(FRSH_ERR_INTERNAL_ERROR,
-                                               "can't get the actual budget for the vres");
-                       usec_to_timespec(*next_budget, qres_thread_budget);
-               }
-       }
-       if (next_period != NULL)
-               *next_period = tmp_thread_period;
-       if (was_deadline_missed != NULL)
-               *was_deadline_missed = false;
-       if (was_budget_overran != NULL)
-               *was_budget_overran = false;
-
-       return FRSH_NO_ERROR;
-}
-