更新日期: 2022/06/01 来源: https://gitee.com/weharmony/kernel_liteos_a_note
los_lockdep.h 文件参考

浏览源代码.

结构体

struct  HeldLocks
 
struct  LockDep
 

类型定义

typedef struct Spinlock SPIN_LOCK_S
 

枚举

enum  LockDepErrType {
  LOCKDEP_SUCCESS = 0 , LOCKDEP_ERR_DOUBLE_LOCK , LOCKDEP_ERR_DEAD_LOCK , LOCKDEP_ERR_UNLOCK_WITOUT_LOCK ,
  LOCKDEP_ERR_OVERFLOW
}
 

函数

VOID OsLockDepCheckIn (SPIN_LOCK_S *lock)
 
VOID OsLockDepRecord (SPIN_LOCK_S *lock)
 
VOID OsLockDepCheckOut (SPIN_LOCK_S *lock)
 
VOID OsLockdepClearSpinlocks (VOID)
 

类型定义说明

◆ SPIN_LOCK_S

typedef struct Spinlock SPIN_LOCK_S

在文件 los_lockdep.h41 行定义.

枚举类型说明

◆ LockDepErrType

枚举值
LOCKDEP_SUCCESS 
LOCKDEP_ERR_DOUBLE_LOCK 
LOCKDEP_ERR_DEAD_LOCK 
LOCKDEP_ERR_UNLOCK_WITOUT_LOCK 
LOCKDEP_ERR_OVERFLOW 

在文件 los_lockdep.h45 行定义.

45 {
50 /* overflow, needs expand */
52};
@ LOCKDEP_ERR_DEAD_LOCK
Definition: los_lockdep.h:48
@ LOCKDEP_SUCCESS
Definition: los_lockdep.h:46
@ LOCKDEP_ERR_UNLOCK_WITOUT_LOCK
Definition: los_lockdep.h:49
@ LOCKDEP_ERR_DOUBLE_LOCK
Definition: los_lockdep.h:47
@ LOCKDEP_ERR_OVERFLOW
Definition: los_lockdep.h:51

函数说明

◆ OsLockDepCheckIn()

VOID OsLockDepCheckIn ( SPIN_LOCK_S lock)
Description:
This API is used to check dead lock in spinlock.
注意
  • The parameter passed in should be ensured to be a legal pointer.
参数
lock[IN] point to a SPIN_LOCK_S.
返回值
None.
Dependency:
  • los_lockdep.h: the header file that contains the API declaration.
参见

在文件 los_lockdep.c189 行定义.

190{
191 UINT32 intSave;
192 enum LockDepErrType checkResult = LOCKDEP_SUCCESS;
193#ifdef LOSCFG_COMPILER_CLANG_LLVM
194 VOID *requestAddr = (VOID *)__builtin_return_address(1);
195#else
196 VOID *requestAddr = (VOID *)__builtin_return_address(0);
197#endif
198 LosTaskCB *current = OsCurrTaskGet();
199 LockDep *lockDep = &current->lockDep;
200 LosTaskCB *lockOwner = NULL;
201
202 OsLockDepRequire(&intSave);
203
204 if (lockDep->lockDepth >= (INT32)MAX_LOCK_DEPTH) {
205 checkResult = LOCKDEP_ERR_OVERFLOW;
206 goto OUT;
207 }
208
209 lockOwner = lock->owner;
210 /* not owned by any tasks yet, not doing following checks */
211 if (lockOwner == SPINLOCK_OWNER_INIT) {
212 goto OUT;
213 }
214
215 if (current == lockOwner) {
216 checkResult = LOCKDEP_ERR_DOUBLE_LOCK;
217 goto OUT;
218 }
219
220 if (OsLockDepCheckDependency(current, lockOwner) != TRUE) {
221 checkResult = LOCKDEP_ERR_DEAD_LOCK;
222 goto OUT;
223 }
224
225OUT:
226 if (checkResult == LOCKDEP_SUCCESS) {
227 /*
228 * though the check may succeed, the waitLock still need to be set.
229 * because the OsLockDepCheckIn and OsLockDepRecord is not strictly multi-core
230 * sequential, there would be more than two tasks can pass the checking, but
231 * only one task can successfully obtain the lock.
232 */
233 lockDep->waitLock = lock;
234 lockDep->heldLocks[lockDep->lockDepth].lockAddr = requestAddr;
235 lockDep->heldLocks[lockDep->lockDepth].waitTime = OsLockDepGetCycles(); /* start time */
236 OsLockDepRelease(intSave);
237 return;
238 }
239 OsLockDepDumpLock(current, lock, requestAddr, checkResult);
240 OsLockDepRelease(intSave);
241 OsLockDepPanic(checkResult);
242}
STATIC BOOL OsLockDepCheckDependency(const LosTaskCB *current, LosTaskCB *lockOwner)
Definition: los_lockdep.c:168
STATIC INLINE UINT64 OsLockDepGetCycles(VOID)
Definition: los_lockdep.c:63
WEAK VOID OsLockDepPanic(enum LockDepErrType errType)
Definition: los_lockdep.c:97
STATIC VOID OsLockDepDumpLock(const LosTaskCB *task, const SPIN_LOCK_S *lock, const VOID *requestAddr, enum LockDepErrType errType)
Definition: los_lockdep.c:130
STATIC INLINE VOID OsLockDepRequire(UINT32 *intSave)
Definition: los_lockdep.c:49
STATIC INLINE VOID OsLockDepRelease(UINT32 intSave)
Definition: los_lockdep.c:57
LockDepErrType
Definition: los_lockdep.h:45
STATIC INLINE LosTaskCB * OsCurrTaskGet(VOID)
signed int INT32
Definition: los_typedef.h:60
unsigned int UINT32
Definition: los_typedef.h:57
VOID * lockAddr
Definition: los_lockdep.h:56
UINT64 waitTime
Definition: los_lockdep.h:57
INT32 lockDepth
Definition: los_lockdep.h:63
HeldLocks heldLocks[MAX_LOCK_DEPTH]
Definition: los_lockdep.h:64
VOID * waitLock
Definition: los_lockdep.h:62
VOID * owner
Definition: los_spinlock.h:54
LockDep lockDep
死锁依赖检测
函数调用图:

◆ OsLockDepCheckOut()

VOID OsLockDepCheckOut ( SPIN_LOCK_S lock)
Description:
This API is used to trace when a spinlock unlocked.
注意
  • The parameter passed in should be ensured to be a legal pointer.
参数
lock[IN] point to a SPIN_LOCK_S.
返回值
None.
Dependency:
  • los_lockdep.h: the header file that contains the API declaration.
参见

在文件 los_lockdep.c274 行定义.

275{
276 UINT32 intSave;
277 INT32 depth;
278 enum LockDepErrType checkResult = LOCKDEP_SUCCESS;
279#ifdef LOSCFG_COMPILER_CLANG_LLVM
280 VOID *requestAddr = (VOID *)__builtin_return_address(1);
281#else
282 VOID *requestAddr = (VOID *)__builtin_return_address(0);
283#endif
284 LosTaskCB *current = OsCurrTaskGet();
285 LosTaskCB *owner = NULL;
286 LockDep *lockDep = NULL;
287 HeldLocks *heldlocks = NULL;
288
289 OsLockDepRequire(&intSave);
290
291 owner = lock->owner;
292 if (owner == SPINLOCK_OWNER_INIT) {
293 checkResult = LOCKDEP_ERR_UNLOCK_WITOUT_LOCK;
294 OsLockDepDumpLock(current, lock, requestAddr, checkResult);
295 OsLockDepRelease(intSave);
296 OsLockDepPanic(checkResult);
297 return;
298 }
299
300 lockDep = &owner->lockDep;
301 heldlocks = &lockDep->heldLocks[0];
302 depth = lockDep->lockDepth;
303
304 /* find the lock position */
305 while (--depth >= 0) {
306 if (heldlocks[depth].lockPtr == lock) {
307 break;
308 }
309 }
310
311 LOS_ASSERT(depth >= 0);
312
313 /* record lock holding time */
314 heldlocks[depth].holdTime = OsLockDepGetCycles() - heldlocks[depth].holdTime;
315
316 /* if unlock an older lock, needs move heldLock records */
317 while (depth < lockDep->lockDepth - 1) {
318 lockDep->heldLocks[depth] = lockDep->heldLocks[depth + 1];
319 depth++;
320 }
321
322 lockDep->lockDepth--;
323 lock->cpuid = (UINT32)(-1);
324 lock->owner = SPINLOCK_OWNER_INIT;
325
326 OsLockDepRelease(intSave);
327}
UINT64 holdTime
Definition: los_lockdep.h:58
UINT32 cpuid
Definition: los_spinlock.h:53
函数调用图:

◆ OsLockdepClearSpinlocks()

VOID OsLockdepClearSpinlocks ( VOID  )
Description:
This API is used to clear lockdep record of curret task.
注意
  • None.
参数
None
返回值
None.
Dependency:
  • los_lockdep.h: the header file that contains the API declaration.
参见

在文件 los_lockdep.c329 行定义.

330{
331 LosTaskCB *task = OsCurrTaskGet();
332 LockDep *lockDep = &task->lockDep;
333 SPIN_LOCK_S *lock = NULL;
334
335 /*
336 * Unlock spinlocks that running task has held.
337 * lockDepth will decrease after each spinlock is unlockded.
338 */
339 while (lockDep->lockDepth) {
340 lock = lockDep->heldLocks[lockDep->lockDepth - 1].lockPtr;
341 LOS_SpinUnlock(lock);
342 }
343}
VOID LOS_SpinUnlock(SPIN_LOCK_S *lock)
Definition: los_spinlock.c:84
VOID * lockPtr
Definition: los_lockdep.h:55
函数调用图:

◆ OsLockDepRecord()

VOID OsLockDepRecord ( SPIN_LOCK_S lock)
Description:
This API is used to trace when a spinlock locked.
注意
  • The parameter passed in should be ensured to be a legal pointer.
参数
lock[IN] point to a SPIN_LOCK_S.
返回值
None.
Dependency:
  • los_lockdep.h: the header file that contains the API declaration.
参见

在文件 los_lockdep.c244 行定义.

245{
246 UINT32 intSave;
247 UINT64 cycles;
248 LosTaskCB *current = OsCurrTaskGet();
249 LockDep *lockDep = &current->lockDep;
250 HeldLocks *heldlock = &lockDep->heldLocks[lockDep->lockDepth];
251
252 OsLockDepRequire(&intSave);
253
254 /*
255 * OsLockDepCheckIn records start time t1, after the lock is obtained, we
256 * get the time t2, (t2 - t1) is the time of waiting for the lock
257 */
258 cycles = OsLockDepGetCycles();
259 heldlock->waitTime = cycles - heldlock->waitTime;
260 heldlock->holdTime = cycles;
261
262 /* record lock info */
263 lock->owner = current;
264 lock->cpuid = ArchCurrCpuid();
265
266 /* record lockdep info */
267 heldlock->lockPtr = lock;
268 lockDep->lockDepth++;
269 lockDep->waitLock = NULL;
270
271 OsLockDepRelease(intSave);
272}
STATIC INLINE UINT32 ArchCurrCpuid(VOID)
Definition: los_hw_cpu.h:168
long unsigned int UINT64
Definition: los_typedef.h:66
函数调用图: