Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset 15d9fe6 in mainline


Ignore:
Timestamp:
2017-10-28T11:26:43Z (4 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master
Children:
c1f68b0
Parents:
7cf8522
Message:

Implement recursive mutex

Location:
kernel/generic
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • kernel/generic/include/synch/mutex.h

    r7cf8522 r15d9fe6  
    4343typedef enum {
    4444        MUTEX_PASSIVE,
     45        MUTEX_RECURSIVE,
    4546        MUTEX_ACTIVE
    4647} mutex_type_t;
     48
     49struct thread;
    4750
    4851typedef struct {
    4952        mutex_type_t type;
    5053        semaphore_t sem;
     54        struct thread *owner;
     55        unsigned nesting;
    5156} mutex_t;
    5257
  • kernel/generic/src/synch/mutex.c

    r7cf8522 r15d9fe6  
    4646/** Initialize mutex.
    4747 *
    48  * @param mtx  Mutex.
    49  * @param type Type of the mutex.
     48 * @param mtx   Mutex.
     49 * @param type  Type of the mutex.
    5050 */
    5151void mutex_initialize(mutex_t *mtx, mutex_type_t type)
    5252{
    5353        mtx->type = type;
     54        mtx->owner = NULL;
     55        mtx->nesting = 0;
    5456        semaphore_initialize(&mtx->sem, 1);
    5557}
     
    5759/** Find out whether the mutex is currently locked.
    5860 *
    59  * @param mtx           Mutex.
    60  * @return              True if the mutex is locked, false otherwise.
     61 * @param mtx  Mutex.
     62 *
     63 * @return  True if the mutex is locked, false otherwise.
    6164 */
    6265bool mutex_locked(mutex_t *mtx)
     
    7174 * Timeout mode and non-blocking mode can be requested.
    7275 *
    73  * @param mtx   Mutex.
    74  * @param usec  Timeout in microseconds.
    75  * @param flags Specify mode of operation.
     76 * @param mtx    Mutex.
     77 * @param usec   Timeout in microseconds.
     78 * @param flags  Specify mode of operation.
    7679 *
    77  * For exact description of possible combinations of
    78  * usec and flags, see comment for waitq_sleep_timeout().
     80 * For exact description of possible combinations of usec and flags, see
     81 * comment for waitq_sleep_timeout().
    7982 *
    8083 * @return See comment for waitq_sleep_timeout().
     
    8588        int rc;
    8689
    87         if ((mtx->type == MUTEX_PASSIVE) && (THREAD)) {
     90        if (mtx->type == MUTEX_PASSIVE && THREAD) {
    8891                rc = _semaphore_down_timeout(&mtx->sem, usec, flags);
     92        } else if (mtx->type == MUTEX_RECURSIVE) {
     93                assert(THREAD);
     94
     95                if (mtx->owner == THREAD) {
     96                        mtx->nesting++;
     97                        return ESYNCH_OK_ATOMIC;
     98                } else {
     99                        rc = _semaphore_down_timeout(&mtx->sem, usec, flags);
     100                        if (SYNCH_OK(rc)) {
     101                                mtx->owner = THREAD;
     102                                mtx->nesting = 1;
     103                        }
     104                }
    89105        } else {
    90                 assert((mtx->type == MUTEX_ACTIVE) || (!THREAD));
     106                assert((mtx->type == MUTEX_ACTIVE) || !THREAD);
    91107                assert(usec == SYNCH_NO_TIMEOUT);
    92108                assert(!(flags & SYNCH_FLAGS_INTERRUPTIBLE));
     
    114130/** Release mutex.
    115131 *
    116  * @param mtx Mutex.
     132 * @param mtx  Mutex.
    117133 */
    118134void mutex_unlock(mutex_t *mtx)
    119135{
     136        if (mtx->type == MUTEX_RECURSIVE) {
     137                assert(mtx->owner == THREAD);
     138                if (--mtx->nesting > 0)
     139                        return;
     140                mtx->owner = NULL;
     141        }
    120142        semaphore_up(&mtx->sem);
    121143}
Note: See TracChangeset for help on using the changeset viewer.