X-Git-Url: https://rtime.felk.cvut.cz/gitweb/frescor/fosa.git/blobdiff_plain/29660bd13b283860b273f7c3d310cd6e696efe1d..46da828932c045058077b3d91517e7b29d2a8010:/src_aquosa/fosa_mutexes_and_condvars.c diff --git a/src_aquosa/fosa_mutexes_and_condvars.c b/src_aquosa/fosa_mutexes_and_condvars.c index 05ac5e6..c40e856 100644 --- a/src_aquosa/fosa_mutexes_and_condvars.c +++ b/src_aquosa/fosa_mutexes_and_condvars.c @@ -58,55 +58,140 @@ // FOSA(Frescor Operating System Adaptation layer) //================================================ -#include - +#include "fosa_mutexes_and_condvars.h" /******************************************************* * Mutexes with priority/bandwidth inheritance ******************************************************/ - +/** + * fosa_mutex_init() + * + * Initialize a frsh mutex + * + * The mutex pointed to by mutex is initialized as a mutex using + * the priority ceiling protocol. A priority ceiling of prioceiling + * is assigned to this mutex. + * + * Returns 0 if successful; otherwise it returns an error code: + * EINVAL: the value of prioceiling is invalid + * EAGAIN: the system lacked the necessary resources to create the mutex + * ENOMEM: Insufficient memory exists to initialize the mutex + * EBUSY: The system has detected an attempt to reinitialize the mutex + **/ int fosa_mutex_init(fosa_mutex_t *mutex, int prioceiling) { - //pthread_mutexattr_t mutex_attr; - - /* prioceiling serves as a flag */ - /* if (prioceiling) { - pthread_mutexattr_init(&mutex_attr); - pthread_mutexattr_setprotocol(&mutex_attr, PTHREAD_PRIO_INHERIT); - - return pthread_mutex_init(mutex, &mutex_attr); - } else */ - return pthread_mutex_init(mutex, NULL); + int error; + pthread_mutexattr_t attr; + + if ((error = pthread_mutexattr_init(&attr)) != 0) + return error; + + if ((error = pthread_mutexattr_setprotocol(&attr, PTHREAD_PRIO_INHERIT)) != 0) + return error; + + return pthread_mutex_init(mutex, &attr); } +/** + * fosa_mutex_destroy() + * + * Destroy a frsh mutex + * + * The mutex pointed to by mutex is destroyed + * + * Returns 0 if successful; otherwise it returns an error code: + * EINVAL: the value of mutex is invalid + * EBUSY: The mutex is in use (is locked) + **/ int fosa_mutex_destroy(fosa_mutex_t *mutex) { return pthread_mutex_destroy(mutex); } +/** + * fosa_mutex_set_prioceiling() + * + * Dynamically set the priority ceiling of a mutex + * + * Since in this implementation we use BandWidth Inheritance defining the + * ceiling of a mutex is meaningless, and so the function always returns + * EINVAL + **/ int fosa_mutex_set_prioceiling(fosa_mutex_t *mutex, - int new_ceiling, - int *old_ceiling) + int new_ceiling, + int *old_ceiling) { - return -1; + return -EINVAL; } +/** + * fosa_mutex_get_prioceiling() + * + * Dynamically get the priority ceiling of a mutex + * + * Since in this implementation we use BandWidth Inheritance defining the + * ceiling of a mutex is meaningless, and so the function always returns + * EINVAL + **/ int fosa_mutex_get_prioceiling(const fosa_mutex_t *mutex, int *ceiling) { - return -1; + return -EINVAL; } +/** + * fosa_mutex_lock() + * + * Lock a mutex + * + * This function locks the mutex specified by mutex. If it is already + * locked, the calling thread blocks until the mutex becomes + * available. The operation returns with the mutex in the locked + * state, with the calling thread as its owner. + * + * Returns 0 if successful; otherwise it returns an error code: + * EINVAL: the value of mutex is invalid, or the priority of the + * calling thread is higher than the priority ceiling of the mutex + * EDEADLK: the current thread already owns this mutex + **/ int fosa_mutex_lock(fosa_mutex_t *mutex) { return pthread_mutex_lock(mutex); } +/** + * fosa_mutex_trylock() + * + * Try locking a mutex + * + * This function is identical to fosa_mutex_lock() except that if the + * mutex is already locked the call returns immediately with an error + * indication. + * + * Returns 0 if successful; otherwise it returns an error code: + * EINVAL: the value of mutex is invalid, or the priority of the + * calling thread is higher than the priority ceiling of the mutex + * EBUSY: the mutex was already locked + **/ int fosa_mutex_trylock(fosa_mutex_t *mutex) { return pthread_mutex_trylock(mutex); } +/** + * fosa_mutex_unlock() + * + * Unlock a mutex + * + * This function must be called by the owner of the mutex referenced + * by mutex, to unlock it. If there are threads blocked on the mutex + * the mutex becomes available and the highest priority thread is + * awakened to acquire the mutex. + * + * Returns 0 if successful; otherwise it returns an error code: + * EINVAL: the value of mutex is invalid + * EPERM: the calling thread is not the owner of the mutex + **/ int fosa_mutex_unlock(fosa_mutex_t *mutex) { return pthread_mutex_unlock(mutex); @@ -116,35 +201,116 @@ int fosa_mutex_unlock(fosa_mutex_t *mutex) * Condition variables *********************/ +/** + * fosa_cond_init() + * + * Initiatize a condition variable + * + * The condition variable referenced by cond is initialized with + * the attributes required by the FOSA implementation. + * + * Returns 0 if successful; otherwise it returns an error code: + * EAGAIN: the system lacked the necessary resources to create the + * condition variable + * ENOMEM: Insufficient memory exists to initialize the condition variable + * EBUSY: The system has detected an attempt to reinitialize the + * condition variable + **/ int fosa_cond_init(fosa_cond_t *cond) { return pthread_cond_init(cond, NULL); } +/** + * fosa_cond_destroy() + * + * Destroy a condition variable + * + * The condition variable pointed to by cond is destroyed + * + * Returns 0 if successful; otherwise it returns an error code: + * EINVAL: the value of cond is invalid + * EBUSY: The condition variable is in use (a thread is waiting on it) + **/ int fosa_cond_destroy(fosa_cond_t *cond) { return pthread_cond_destroy(cond); } +/** + * fosa_cond_signal() + * + * Signal a condition variable + * + * This call unblocks at least one of the threads that are waiting on + * the condition variable referenced by cond. If there are no threads + * waiting, the function has no effect + * + * Returns 0 if successful; otherwise it returns an error code: + * EINVAL: the value of cond is invalid + **/ int fosa_cond_signal(fosa_cond_t *cond) { return pthread_cond_signal(cond); } +/** + * fosa_cond_broadcast() + * + * Broadcast a condition variable + * + * This call unblocks all of the threads that are waiting on the + * condition variable referenced by cond. If there are no threads + * waiting, the function has no effect. + * + * Returns 0 if successful; otherwise it returns an error code: + * EINVAL: the value of cond is invalid + **/ int fosa_cond_broadcast(fosa_cond_t *cond) { return pthread_cond_broadcast(cond); } +/** + * fosa_cond_wait() + * + * Wait at a condition variable + * + * This call is used to block on the condition variable referenced by + * cond. It shall be called with the mutex referenced by mutex + * locked. The function releases the mutex and blocks the calling + * thread until the condition is signalled by some other thread and + * the calling thread is awakened. Then it locks the mutex and + * returns with the mutex locked by the calling thread. + * + * Returns 0 if successful; otherwise it returns an error code: + * EINVAL: the value of cond or mutex is invalid, or different + * mutexes were used for concurrent wait operations on cond, or + * the mutex was not owned by the calling thread + **/ int fosa_cond_wait(fosa_cond_t *cond, fosa_mutex_t *mutex) { return pthread_cond_wait(cond, mutex); } +/** + * fosa_cond_timedwait() + * + * Wait at a condition variable, with a timeout + * + * This function is equal to fosa_cond_wait(), except that the maximum + * wait time is limited to the absolute time referenced by abstime, as + * measured by the FOSA_CLOCK_ABSOLUTE clock. + * + * Returns 0 if successful; otherwise it returns an error code: + * EINVAL: the value of cond or mutex or abstime is invalid, or different + * mutexes were used for concurrent wait operations on cond, or + * the mutex was not owned by the calling thread + * ETIMEDOUT: the timeout expired + **/ int fosa_cond_timedwait(fosa_cond_t *cond, fosa_mutex_t *mutex, const struct timespec *abstime) { return pthread_cond_timedwait(cond, mutex, abstime); } -