* This file contains the implementation of FRSH API core functions on top
* of the AQuoSA framework, on GNU/Linux platform.
*
- * It's the main file in which all the function are defined but many of them
- * are implemented via a request to the service thread through a socket
- * connection.
- * For the details of the API functions implementation take a look
- * into the frsh_service_th.c (and related headers) source file.
- *
- * The FRSH core API is actually completely implemented and almost all
- * functions behave as described by the FRSH deliverables and specifications
- * documents.
- * There still could be some differences, maily due by the peculiarities of
- * the AQuoSA framework, and they're briefly discussed in the comments leading
- * any of the function definition and/or in separate documents
- *
- * The most significant issue with the actual implementation is it's limited
- * to INDETERMINATE contracts, because of the status of the AQuoSA framework
- * on th 2.6.x Linux platforms.
- * Support for BOUNDED workload will came as soon as the QoS manager (qmgr) of
- * AQuoSA will be in place
*/
/* Linux files */
/* local timepsec <-> usec utility macros */
#include "timespec_usec_ops.h"
-/*
- * 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 sinchronization mechanism based on signals is realized.
- * Also the some of the return values are handled this way (using signals)
- *
- * possible return values:
- * see below the comments of each specific API call
- */
-/*
+/**
* structure used to pass the new created thread (or better its wrapper) the
* arguments it needs to bind itself to the vres.
- *
- * Note it also include (in 'pthread_code' and in 'pthread_arg') effective
- * thread code and argument provided by the user to the original API
- * 'frsh_thread_create_and_bind()' call
*/
typedef struct {
frsh_thread_id_t parent_thread_id;
frsh_thread_id_t *thread_id;
- frsh_thread_code_t pthread_code;
- void *pthread_arg;
+ 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;
+ sem_t *stopper; /**< semaphore to synchronize frsh call and wrapper thread */
int errcode;
} wrapper_pthread_arg_t;
pid_t linux_tid;
} FOSA_THREAD_ID_T_OPAQUE;*/
-
-
-/*
+/**
* frsh_thread_bind(), bind a thread to a vres
*
- * Asks the service thread for binding of a thread to a valid, REGULAR and
- * contracetd vres.
- * If all is ok the thread is attached to an AQuoSA resource reservation server
- *
- * As usual the code below simply prepares a message, send it and wait for
- * the answer from the service thread, for details on the implementation check
- * 'bind_thread()' in the frsh_service_th.c source file
-
* possible return values:
* FRSH_NO_ERROR
* FRSH_ERR_NOT_INITIALIZED
* 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)
- * FRSH_ERR_INVALID_SCHEDULER_REPLY (error in communication with the service thread)
*/
int frsh_thread_bind(const frsh_vres_id_t vres, const frsh_thread_id_t thread)
{
qos_rv qrv;
qres_sid_t sid = *((qres_sid_t*)vres->priv);
+ /*if (!aqcpu_is_initialized) {
+ return(FRSH_ERR_NOT_INITIALIZED);
+ }*/
+
printf("BIND:sid = %d, pid = %d, tid= %d\n", sid,
thread.linux_pid, thread.linux_tid);
+
if ((qrv = qres_attach_thread(sid, thread.linux_pid,
thread.linux_tid)) != QOS_OK) {
- return qos_rv_int(qrv);
+ /* return qos_rv_int(qrv);*/
+ return FRSH_ERR_INTERNAL_ERROR;
}
- return 0;
+ return FRSH_NO_ERROR;
}
/*
* frsh_thread_unbind(), unbind a thread from a vres
*
- * Asks the service thread for revoke the binding of a thread to a its actual
- * vres.
- * If all is ok the thread is detached from the AQuoSA resource
- * reservation server.
- *
- * The code below only prepares the message, send it and wait for the answer,
- * for details on the implementation check 'unbind_thread()' in the
- * frsh_service_th.c source file
-
* 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)
- * FRSH_ERR_INVALID_SCHEDULER_REPLY (error in communication with the service thread)
*/
int frsh_thread_unbind(const frsh_thread_id_t thread)
{
if ((qrv = qres_detach_thread(sid, thread.linux_pid,
thread.linux_tid)) != QOS_OK) {
- return qos_rv_int(qrv);
+ /*return qos_rv_int(qrv);*/
+ return FRSH_ERR_INTERNAL_ERROR;
}
- return 0;
+ return FRSH_NO_ERROR;
}
-/*
- * code for the described wrapper, it only asks the service thread the
- * binding of itself to the vres and the directly run the user provided
- * thread code.
- *
- * Note that some of the return values of the API
- * 'frsh_thread_create_and_bind()' or 'frsh_thread_create_in_background()'
- * call are also possible exit status of the new thread
- *
+/**
+ * Wrapper thread
+ *
* possible exit status:
- * FRSH_ERR_INVALID_SCHEDULER_REPLY (error in communication with the service thread)
* FRSH_ERR_INTENRAL_ERROR (something wrong with threads and signal handling)
* FRSH_ERR_TOO_MANY_TASKS(*)
* FRSH_ERR_BAD_ARGUMENT(*) (invalid vres)
frsh_thread_id_t* thread_id = pth->thread_id;
*thread_id = fosa_thread_self();
- printf("Got therad id\n");
printf("Wrapper: pid = %d, tid= %d\n",
thread_id->linux_pid, thread_id->linux_tid);
- printf("Before bind \n");
+ /* bind this thread to vres */
pth->errcode = frsh_thread_bind(pth->vres, *thread_id);
- printf("After bind \n");
sem_post(pth->stopper);
if (pth->errcode) /* vres binding was not successful */
return NULL;
- printf("Launch thread\n");
+
+ /* execute thread function */
return pth->pthread_code(pth->pthread_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
* FRSH_ERR_NOT_INITIALIZED
* FRSH_ERR_BAD_ARGUMENT (NULL thread or thread_code)
* whatever 'fosa_thread_create()' returns
- * FRSH_ERR_INTERNAL_ERROR (something wrong in signal handling)
+ * FRSH_ERR_INTERNAL_ERROR
*/
int frsh_thread_create_and_bind(const frsh_vres_id_t vres,
frsh_thread_id_t *thread,
* The code below only prepares the message, send it and wait for the answer,
* for details on the implementation check 'get_thread_vres_id()' in the
* frsh_service_th.c source file
-
* possible return values:
* FRSH_NO_ERROR
* FRSH_ERR_NOT_INITIALIZED