Changes in kernel/generic/src/synch/mutex.c [76e17d7c:e88eb48] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/src/synch/mutex.c
r76e17d7c re88eb48 1 1 /* 2 2 * Copyright (c) 2001-2004 Jakub Jermar 3 * Copyright (c) 2023 Jiří Zárevúcky4 3 * All rights reserved. 5 4 * … … 67 66 bool mutex_locked(mutex_t *mtx) 68 67 { 69 errno_t rc = semaphore_trydown(&mtx->sem); 70 if (rc == EOK) { 71 semaphore_up(&mtx->sem); 72 } 73 return rc != EOK; 68 return semaphore_count_get(&mtx->sem) <= 0; 74 69 } 75 70 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 } 71 #define MUTEX_DEADLOCK_THRESHOLD 100000000 96 72 97 73 /** Acquire mutex. 98 74 * 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. 75 * Timeout mode and non-blocking mode can be requested. 120 76 * 121 77 * @param mtx Mutex. 122 78 * @param usec Timeout in microseconds. 79 * @param flags Specify mode of operation. 123 80 * 124 * @return EOK if lock was successfully acquired, something else otherwise. 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 * 125 86 */ 126 errno_t mutex_lock_timeout(mutex_t *mtx, uint32_t usec)87 errno_t _mutex_lock_timeout(mutex_t *mtx, uint32_t usec, unsigned int flags) 127 88 { 128 if (usec != 0) { 129 assert(mtx->type != MUTEX_ACTIVE); 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) { 130 94 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); 131 125 } 132 126 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 }144 127 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);154 128 } 155 129
Note:
See TracChangeset
for help on using the changeset viewer.