Changeset 76e17d7c in mainline
- Timestamp:
- 2023-02-11T18:50:54Z (23 months ago)
- Branches:
- master, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 111b9b9
- Parents:
- 11d2c983
- git-author:
- Jiří Zárevúcky <zarevucky.jiri@…> (2023-02-05 15:30:26)
- git-committer:
- Jiří Zárevúcky <zarevucky.jiri@…> (2023-02-11 18:50:54)
- Location:
- kernel/generic
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/include/synch/mutex.h
r11d2c983 r76e17d7c 59 59 extern bool mutex_locked(mutex_t *); 60 60 extern errno_t mutex_trylock(mutex_t *); 61 extern errno_tmutex_lock(mutex_t *);61 extern void mutex_lock(mutex_t *); 62 62 extern errno_t mutex_lock_timeout(mutex_t *, uint32_t); 63 63 extern void mutex_unlock(mutex_t *); -
kernel/generic/include/synch/semaphore.h
r11d2c983 r76e17d7c 46 46 47 47 extern void semaphore_initialize(semaphore_t *, int); 48 extern errno_t _semaphore_down_timeout(semaphore_t *, uint32_t, unsigned);49 48 extern errno_t semaphore_down_timeout(semaphore_t *, uint32_t); 50 49 extern errno_t semaphore_trydown(semaphore_t *); -
kernel/generic/src/synch/mutex.c
r11d2c983 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 * … … 73 74 } 74 75 75 #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 } 76 96 77 97 /** Acquire mutex. 78 98 * 79 * 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. 80 120 * 81 121 * @param mtx Mutex. 82 122 * @param usec Timeout in microseconds. 83 * @param flags Specify mode of operation.84 123 * 85 * For exact description of possible combinations of usec and flags, see 86 * comment for waitq_sleep_timeout(). 87 * 88 * @return See comment for waitq_sleep_timeout(). 89 * 124 * @return EOK if lock was successfully acquired, something else otherwise. 90 125 */ 91 static 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) 92 127 { 93 errno_t rc; 94 95 if (mtx->type == MUTEX_PASSIVE && THREAD) { 96 rc = _semaphore_down_timeout(&mtx->sem, usec, flags); 97 } else if (mtx->type == MUTEX_RECURSIVE) { 128 if (usec != 0) { 129 assert(mtx->type != MUTEX_ACTIVE); 98 130 assert(THREAD); 99 100 if (mtx->owner == THREAD) {101 mtx->nesting++;102 return EOK;103 } else {104 rc = _semaphore_down_timeout(&mtx->sem, usec, flags);105 if (rc == EOK) {106 mtx->owner = THREAD;107 mtx->nesting = 1;108 }109 }110 } else {111 assert((mtx->type == MUTEX_ACTIVE) || !THREAD);112 assert(usec == SYNCH_NO_TIMEOUT);113 assert(!(flags & SYNCH_FLAGS_INTERRUPTIBLE));114 115 unsigned int cnt = 0;116 bool deadlock_reported = false;117 do {118 if (cnt++ > MUTEX_DEADLOCK_THRESHOLD) {119 printf("cpu%u: looping on active mutex %p\n",120 CPU->id, mtx);121 stack_trace();122 cnt = 0;123 deadlock_reported = true;124 }125 rc = semaphore_trydown(&mtx->sem);126 } while (rc != EOK && !(flags & SYNCH_FLAGS_NON_BLOCKING));127 if (deadlock_reported)128 printf("cpu%u: not deadlocked\n", CPU->id);129 131 } 130 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 } 131 144 return rc; 132 145 } 133 146 147 /** Attempt to acquire mutex without blocking. 148 * 149 * @return EOK if lock was successfully acquired, something else otherwise. 150 */ 134 151 errno_t mutex_trylock(mutex_t *mtx) 135 152 { 136 return _mutex_lock_timeout(mtx, SYNCH_NO_TIMEOUT, SYNCH_FLAGS_NON_BLOCKING); 137 } 138 139 errno_t mutex_lock(mutex_t *mtx) 140 { 141 return _mutex_lock_timeout(mtx, SYNCH_NO_TIMEOUT, SYNCH_FLAGS_NONE); 142 } 143 144 errno_t mutex_lock_timeout(mutex_t *mtx, uint32_t usec) 145 { 146 return _mutex_lock_timeout(mtx, usec, SYNCH_FLAGS_NON_BLOCKING); 153 return mutex_lock_timeout(mtx, 0); 147 154 } 148 155 -
kernel/generic/src/synch/semaphore.c
r11d2c983 r76e17d7c 55 55 } 56 56 57 errno_t _semaphore_down_timeout(semaphore_t *sem, uint32_t usec, unsigned flags)58 {59 errno_t rc = waitq_sleep_timeout(&sem->wq, usec, flags, NULL);60 assert(rc == EOK || rc == ETIMEOUT || rc == EAGAIN);61 return rc;62 }63 64 57 errno_t semaphore_trydown(semaphore_t *sem) 65 58 { 66 return _semaphore_down_timeout(sem, SYNCH_NO_TIMEOUT, SYNCH_FLAGS_NON_BLOCKING);59 return semaphore_down_timeout(sem, 0); 67 60 } 68 61 … … 77 70 errno_t semaphore_down_timeout(semaphore_t *sem, uint32_t usec) 78 71 { 79 return _semaphore_down_timeout(sem, usec, SYNCH_FLAGS_NON_BLOCKING); 72 errno_t rc = waitq_sleep_timeout(&sem->wq, usec, SYNCH_FLAGS_NON_BLOCKING, NULL); 73 assert(rc == EOK || rc == ETIMEOUT || rc == EAGAIN); 74 return rc; 80 75 } 81 76
Note:
See TracChangeset
for help on using the changeset viewer.