Changes in kernel/generic/src/synch/mutex.c [e88eb48:76e17d7c] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/src/synch/mutex.c
re88eb48 r76e17d7c 1 1 /* 2 2 * Copyright (c) 2001-2004 Jakub Jermar 3 * Copyright (c) 2023 Jiří Zárevúcky 3 4 * All rights reserved. 4 5 * … … 66 67 bool mutex_locked(mutex_t *mtx) 67 68 { 68 return semaphore_count_get(&mtx->sem) <= 0; 69 errno_t rc = semaphore_trydown(&mtx->sem); 70 if (rc == EOK) { 71 semaphore_up(&mtx->sem); 72 } 73 return rc != EOK; 69 74 } 70 75 71 #define MUTEX_DEADLOCK_THRESHOLD 100000000 76 static void mutex_lock_active(mutex_t *mtx) 77 { 78 assert((mtx->type == MUTEX_ACTIVE) || !THREAD); 79 80 const unsigned deadlock_treshold = 100000000; 81 unsigned int cnt = 0; 82 bool deadlock_reported = false; 83 84 while (semaphore_trydown(&mtx->sem) != EOK) { 85 if (cnt++ > deadlock_treshold) { 86 printf("cpu%u: looping on active mutex %p\n", CPU->id, mtx); 87 stack_trace(); 88 cnt = 0; 89 deadlock_reported = true; 90 } 91 } 92 93 if (deadlock_reported) 94 printf("cpu%u: not deadlocked\n", CPU->id); 95 } 72 96 73 97 /** Acquire mutex. 74 98 * 75 * Timeout mode and non-blocking mode can be requested. 99 * This operation is uninterruptible and cannot fail. 100 */ 101 void mutex_lock(mutex_t *mtx) 102 { 103 if (mtx->type == MUTEX_RECURSIVE && mtx->owner == THREAD) { 104 assert(THREAD); 105 mtx->nesting++; 106 return; 107 } 108 109 if (mtx->type == MUTEX_ACTIVE || !THREAD) { 110 mutex_lock_active(mtx); 111 return; 112 } 113 114 semaphore_down(&mtx->sem); 115 mtx->owner = THREAD; 116 mtx->nesting = 1; 117 } 118 119 /** Acquire mutex with timeout. 76 120 * 77 121 * @param mtx Mutex. 78 122 * @param usec Timeout in microseconds. 79 * @param flags Specify mode of operation.80 123 * 81 * For exact description of possible combinations of usec and flags, see 82 * comment for waitq_sleep_timeout(). 83 * 84 * @return See comment for waitq_sleep_timeout(). 85 * 124 * @return EOK if lock was successfully acquired, something else otherwise. 86 125 */ 87 errno_t _mutex_lock_timeout(mutex_t *mtx, uint32_t usec, unsigned int flags)126 errno_t mutex_lock_timeout(mutex_t *mtx, uint32_t usec) 88 127 { 89 errno_t rc; 90 91 if (mtx->type == MUTEX_PASSIVE && THREAD) { 92 rc = _semaphore_down_timeout(&mtx->sem, usec, flags); 93 } else if (mtx->type == MUTEX_RECURSIVE) { 128 if (usec != 0) { 129 assert(mtx->type != MUTEX_ACTIVE); 94 130 assert(THREAD); 95 96 if (mtx->owner == THREAD) {97 mtx->nesting++;98 return EOK;99 } else {100 rc = _semaphore_down_timeout(&mtx->sem, usec, flags);101 if (rc == EOK) {102 mtx->owner = THREAD;103 mtx->nesting = 1;104 }105 }106 } else {107 assert((mtx->type == MUTEX_ACTIVE) || !THREAD);108 assert(usec == SYNCH_NO_TIMEOUT);109 assert(!(flags & SYNCH_FLAGS_INTERRUPTIBLE));110 111 unsigned int cnt = 0;112 bool deadlock_reported = false;113 do {114 if (cnt++ > MUTEX_DEADLOCK_THRESHOLD) {115 printf("cpu%u: looping on active mutex %p\n",116 CPU->id, mtx);117 stack_trace();118 cnt = 0;119 deadlock_reported = true;120 }121 rc = semaphore_trydown(&mtx->sem);122 } while (rc != EOK && !(flags & SYNCH_FLAGS_NON_BLOCKING));123 if (deadlock_reported)124 printf("cpu%u: not deadlocked\n", CPU->id);125 131 } 126 132 133 if (mtx->type == MUTEX_RECURSIVE && mtx->owner == THREAD) { 134 assert(THREAD); 135 mtx->nesting++; 136 return EOK; 137 } 138 139 errno_t rc = semaphore_down_timeout(&mtx->sem, usec); 140 if (rc == EOK) { 141 mtx->owner = THREAD; 142 mtx->nesting = 1; 143 } 127 144 return rc; 145 } 146 147 /** Attempt to acquire mutex without blocking. 148 * 149 * @return EOK if lock was successfully acquired, something else otherwise. 150 */ 151 errno_t mutex_trylock(mutex_t *mtx) 152 { 153 return mutex_lock_timeout(mtx, 0); 128 154 } 129 155
Note:
See TracChangeset
for help on using the changeset viewer.