📄 lislocks.c
字号:
{ while (lis_own_spl()) lis_spin_unlock_irqrestore_fcn(&lis_spl_lock, &lis_psw0, file, line) ;} /* lis_spl0 *//************************************************************************* lis_spl_init *************************************************************************** ** Called only from LiS init routine. ** *************************************************************************/void lis_spl_init(void){ lis_spin_lock_init(&lis_spl_lock, "LiS_SPL_Lock") ; lis_psw0 = lis_splstr() ; /* capture base-level psw */ lis_splx(lis_psw0) ;}/************************************************************************* lis_own_spl *************************************************************************** ** Return true if this task owns the global lis_spin_lock. ** *************************************************************************/int lis_own_spl(void){ return (lis_spin_is_locked(&lis_spl_lock) && lis_spl_lock.taskp == current);}/************************************************************************* Spin Locks *************************************************************************** ** These are the routines that interface to the kernel's spin lock ** mechanism. ** ** Note for 2.2 implementation: If SMP is not set then the 2.2 kernel ** has "pretend" spin locks that do not even track the state of the ** lock. If SMP is set then the implementation is genuine. HOWEVER, ** the LiS routines do not use the kernel spin lock code. The reason ** is that when LiS is running it owns the "big kernel lock". It can ** happen in SMP situations that one CPU spins on a lock that a second ** thread needs to unlock, but can't because the first CPU is holding ** the "big kernel lock" while spinning. Since the "big kernel lock" ** single threads kernel execution anyway the spin locks are not ** necessary to proper driver function. For the "irq" related spin ** lock functions we do the "cli" part, just not the spin lock part. ** *************************************************************************/int lis_spin_is_locked_fcn(lis_spin_lock_t *lock, FL){ DCL_l ; (void) file; (void) line ; (void) l ; /* compiler happiness in 2.2 */#if defined(KERNEL_2_3) /* 2.3 kernel or later */# if defined(_PPC_LIS_) return(0) ; /* PPC does not define this, odd */# else return(spin_is_locked(l)) ;# endif#elif defined(KERNEL_2_1) /* 2.1 and 2.2 kernels */# if defined (__SMP__) return((*((volatile int *) (&l->lock))) == 1) ; /* lock state exists */# else return(0) ; /* lock state not tracked */# endif#else /* earlier kernels */ return(0) ; /* LOL with 2.0 kernels */#endif}void lis_spin_lock_fcn(lis_spin_lock_t *lock, FL){ int prev ; DCL_l ; (void) l ; /* suppress compiler warning */ lis_atomic_inc(&lis_spin_lock_count) ; SAVE_FLAGS(prev); SET_SPINNER if ((void *) current != lock->taskp) {#if defined(KERNEL_2_3) /* 2.3 kernel or later */ if (spin_is_locked(l)) lis_atomic_inc(&lis_spin_lock_contention_count) ; spin_lock(l) ;#endif lock->taskp = (void *) current ; SET_OWNER } lis_atomic_inc(&lock->nest) ; LOCK_ENTRY(lock,TRACK_LOCK,file,line,prev)}void lis_spin_unlock_fcn(lis_spin_lock_t *lock, FL){ int prev ; DCL_l ; (void) l ; /* avoid warning in non-SMP case */ SAVE_FLAGS(prev) ; LOCK_EXIT(lock,TRACK_UNLOCK,file,line,prev) if (lis_atomic_read(&lock->nest) > 0) { lis_atomic_dec(&lock->nest) ; if (lis_atomic_read(&lock->nest) == 0) { lock->taskp = NULL ; SET_SPIN_UNLOCK#if defined(KERNEL_2_3) /* 2.3 kernel or later */ spin_unlock(l) ;#endif } }}int lis_spin_trylock_fcn(lis_spin_lock_t *lock, FL){#if defined(KERNEL_2_3) /* 2.3 kernel or later */ int ret ; lis_flags_t prev ; DCL_l ; (void) l ; /* avoid warning in non-SMP case */ (void) prev ; lis_atomic_inc(&lis_spin_lock_count) ; SET_SPINNER if ((void *) current != lock->taskp) { if ((ret = spin_trylock(l)) != 0) { lis_atomic_inc(&lock->nest) ; lock->taskp = (void *) current ; SET_OWNER } else lis_atomic_inc(&lis_spin_lock_contention_count) ; return(ret) ; } return(1) ; /* already held */#else /* 2.2 kernel */ lis_spin_lock_fcn(lock, file, line) ; return(1) ; /* always succeeds */#endif}void lis_spin_lock_irq_fcn(lis_spin_lock_t *lock, FL){ lis_flags_t prev ; DCL_l ; (void) l ; /* compiler happiness in 2.2 */ lis_atomic_inc(&lis_spin_lock_count) ; SAVE_FLAGS(prev) ; SET_SPINNER if ((void *) current != THELOCK->taskp) {#if defined(KERNEL_2_3) /* 2.3 kernel or later */ if (spin_is_locked(l)) lis_atomic_inc(&lis_spin_lock_contention_count) ; spin_lock_irq(l) ;#else /* 2.2 kernel */ cli() ; /* global cli */#endif THELOCK->taskp = (void *) current ; SET_OWNER } lis_atomic_inc(&THELOCK->nest) ; LOCK_ENTRY(lock,TRACK_LOCK,file,line,prev)}void lis_spin_unlock_irq_fcn(lis_spin_lock_t *lock, FL){ lis_flags_t prev ; DCL_l ; (void) l ; /* avoid warning in non-SMP case */ SAVE_FLAGS(prev) ; LOCK_EXIT(lock,TRACK_UNLOCK,file,line,prev) if (lis_atomic_read(&THELOCK->nest) > 0) { lis_atomic_dec(&THELOCK->nest) ; if (lis_atomic_read(&THELOCK->nest) == 0) { THELOCK->taskp = NULL ; SET_SPIN_UNLOCK#if defined(KERNEL_2_3) /* 2.3 kernel or later */ spin_unlock_irq(l) ;#else /* 2.2 kernel */ sti() ; /* global sti */#endif } }}void lis_spin_lock_irqsave_fcn(lis_spin_lock_t *lock, lis_flags_t *flags, FL){ lis_flags_t prev ; DCL_l ; (void) l ; /* compiler happiness in 2.2 */ lis_atomic_inc(&lis_spin_lock_count) ; SAVE_FLAGS(prev) ; SET_SPINNER if ((void *) current != THELOCK->taskp) {#if defined(KERNEL_2_3) /* 2.3 kernel or later */ if (spin_is_locked(l)) lis_atomic_inc(&lis_spin_lock_contention_count) ; spin_lock_irqsave(l, (*flags)) ;#else /* 2.2 kernel */ cli() ; /* global cli */ if (lis_atomic_read(&THELOCK->nest) == 0) *flags = prev ; else *flags = 0xff ; /* invalid */#endif THELOCK->taskp = (void *) current ; SET_OWNER } lis_atomic_inc(&THELOCK->nest) ; LOCK_ENTRY(lock,TRACK_LOCK,file,line,prev)}void lis_spin_unlock_irqrestore_fcn(lis_spin_lock_t *lock, lis_flags_t *flags, FL){ lis_flags_t prev ; DCL_l ; (void) l ; /* avoid warning in non-SMP case */ SAVE_FLAGS(prev) ; LOCK_EXIT(lock,TRACK_UNLOCK,file,line,prev) if (lis_atomic_read(&THELOCK->nest) > 0) { lis_atomic_dec(&THELOCK->nest) ; if (lis_atomic_read(&THELOCK->nest) == 0) { THELOCK->taskp = NULL ; SET_SPIN_UNLOCK#if defined(KERNEL_2_3) /* 2.3 kernel or later */ spin_unlock_irqrestore(l, (*flags)) ;#else /* 2.2 kernel */ if (*flags != 0xff) restore_flags(*flags) ;#endif } }}#if defined(CONFIG_DEV)static void lis_spin_lock_fill(lis_spin_lock_t *lock, const char *name, FL)#elsestatic void lis_spin_lock_fill(lis_spin_lock_t *lock, const char *name)#endif{ DCL_l ; (void) l ; /* avoid warning in non-SMP case */ if (name == NULL) name = "Spin-Lock" ; lock->name = (char *) name ; lock->spinner_file = "Initialized" ; lock->owner_file = lock->spinner_file ; lock->unlocker_file = lock->spinner_file ; lock->unlocker_cntr = ++lis_seq_cntr ; spin_lock_init(l) ; /* kernel's init function */}void lis_spin_lock_init_fcn(lis_spin_lock_t *lock, const char *name, FL){ memset((void *)lock, 0, sizeof(*lock)) ; SPIN_FILL;}lis_spin_lock_t *lis_spin_lock_alloc_fcn(const char *name, FL){ lis_spin_lock_t *lock ; int lock_size ; lock_size = sizeof(*lock) - sizeof(lock->spin_lock_mem) + sizeof(spinlock_t) ; lock = (lis_spin_lock_t *) lis_alloc_kernel_fcn(lock_size, file, line); if (lock == NULL) return(NULL) ; memset((void *)lock, 0, lock_size) ; SPIN_FILL; lock->allocated = 1 ; return(lock) ;}lis_spin_lock_t *lis_spin_lock_free_fcn(lis_spin_lock_t *lock, FL){ if (lock->allocated) lis_free_mem_fcn((void *)lock, file, line) ; return(NULL) ;}/************************************************************************* Read/Write Spin Locks *************************************************************************** ** These are the routines that interface to the kernel's RW lock ** mechanism. ** ** This is a more direct translation than spin locks. There is no need ** to make these locks nestable, that I can think of, so there is less ** messing around with counts. ** ** For 2.2, all these routines are noops. ** *************************************************************************/#if defined(KERNEL_2_3)void lis_rw_read_lock_fcn(lis_rw_lock_t *lock, FL){ lis_flags_t prev ; DCL_r ; (void) r ; /* suppress compiler warning */ SAVE_FLAGS(prev) ; SET_SPINNER read_lock(r) ; lock->taskp = (void *) current ; SET_OWNER LOCK_ENTRY(lock,TRACK_LOCK,file,line,prev)}void lis_rw_write_lock_fcn(lis_rw_lock_t *lock, FL){ lis_flags_t prev ; DCL_r ; (void) r ; /* suppress compiler warning */ SAVE_FLAGS(prev) ; SET_SPINNER write_lock(r) ; lock->taskp = (void *) current ; SET_OWNER LOCK_ENTRY(lock,TRACK_LOCK,file,line,prev)}void lis_rw_read_unlock_fcn(lis_rw_lock_t *lock, FL){ lis_flags_t prev ; DCL_r ; (void) r ; /* avoid warning in non-SMP case */ SAVE_FLAGS(prev) ; LOCK_EXIT(lock,TRACK_UNLOCK,file,line,prev) lock->taskp = NULL ; SET_SPIN_UNLOCK read_unlock(r) ;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -