pthread_mutex_unlock.c
- int
- internal_function attribute_hidden
- __pthread_mutex_unlock_usercnt (mutex, decr)
- pthread_mutex_t *mutex;
- int decr;
- {
- if (__builtin_expect (type, PTHREAD_MUTEX_TIMED_NP)
- == PTHREAD_MUTEX_TIMED_NP)
- {
- /* Always reset the owner field. */
- normal:
- mutex->__data.__owner = 0;
- if (decr)
- /* One less user. */
- --mutex->__data.__nusers;
- /* Unlock. */
- lll_unlock (mutex->__data.__lock, PTHREAD_MUTEX_PSHARED (mutex));
- return 0;
- }
- }
pthread_mutex_unlock将mutex中的owner清空,并调用了lll_unlock方法
lowlevellock.h
- #define __lll_unlock(futex, private)
- ((void) ({
- int *__futex = (futex);
- int __val = atomic_exchange_rel (__futex, 0);
-
- if (__builtin_expect (__val > 1, 0))
- lll_futex_wake (__futex, 1, private);
- }))
- #define lll_unlock(futex, private) __lll_unlock(&(futex), private)
- #define lll_futex_wake(ftx, nr, private)
- ({
- DO_INLINE_SYSCALL(futex, 3, (long) (ftx),
- __lll_private_flag (FUTEX_WAKE, private),
- (int) (nr));
- _r10 == -1 ? -_retval : _retval;
- })
lll_unlock分为两个步骤:
- 将futex设置为0并拿到设置之前的值(用户态操作)
- 如果futex之前的值>1,代表存在锁冲突,也就是说有线程调用了FUTEX_WAIT在休眠,所以通过调用系统函数FUTEX_WAKE唤醒休眠线程
FUTEX_WAKE在上一篇文章有分析,futex机制的核心是当获得锁时,尝试cas更改一个int型变量(用户态操作),如果integer原始值是0,则修改成功,该线程获得锁,否则就将当期线程放入到 wait queue中,wait queue中的线程不会被系统调度(内核态操作)。
futex变量的值有3种:0代表当前锁空闲,1代表有线程持有当前锁,2代表存在锁冲突。futex的值初始化时是0;当调用try_lock的时候会利用cas操作改为1(见上面的trylock函数);当调用lll_lock时,如果不存在锁冲突,则将其改为1,否则改为2。
- #define __lll_lock(futex, private)
- ((void) ({
- int *__futex = (futex);
- if (__builtin_expect (atomic_compare_and_exchange_bool_acq (__futex,
- 1, 0), 0))
- {
- if (__builtin_constant_p (private) && (private) == LLL_PRIVATE)
- __lll_lock_wait_private (__futex);
- else
- __lll_lock_wait (__futex, private);
- }
- }))
- #define lll_lock(futex, private) __lll_lock (&(futex), private)
- void
- __lll_lock_wait_private (int *futex)
- {
- //第一次进来的时候futex==1,所以不会走这个if
- if (*futex == 2)
- lll_futex_wait (futex, 2, LLL_PRIVATE);
- //在这里会把futex设置成2,并调用futex_wait让当前线程等待
- while (atomic_exchange_acq (futex, 2) != 0)
- lll_futex_wait (futex, 2, LLL_PRIVATE);
- }
pthread_cond_timedwait (编辑:晋中站长网)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|