* Lock PTHREAD_PRIO_NONE protocol POSIX mutex. */
| 985 | * Lock PTHREAD_PRIO_NONE protocol POSIX mutex. |
| 986 | */ |
| 987 | static int |
| 988 | do_lock_normal(struct thread *td, struct umutex *m, uint32_t flags, |
| 989 | struct _umtx_time *timeout, int mode) |
| 990 | { |
| 991 | struct abs_timeout timo; |
| 992 | struct umtx_q *uq; |
| 993 | uint32_t owner, old, id; |
| 994 | int error, rv; |
| 995 | |
| 996 | id = td->td_tid; |
| 997 | uq = td->td_umtxq; |
| 998 | error = 0; |
| 999 | if (timeout != NULL) |
| 1000 | abs_timeout_init2(&timo, timeout); |
| 1001 | |
| 1002 | /* |
| 1003 | * Care must be exercised when dealing with umtx structure. It |
| 1004 | * can fault on any access. |
| 1005 | */ |
| 1006 | for (;;) { |
| 1007 | rv = fueword32(&m->m_owner, &owner); |
| 1008 | if (rv == -1) |
| 1009 | return (EFAULT); |
| 1010 | if (mode == _UMUTEX_WAIT) { |
| 1011 | if (owner == UMUTEX_UNOWNED || |
| 1012 | owner == UMUTEX_CONTESTED || |
| 1013 | owner == UMUTEX_RB_OWNERDEAD || |
| 1014 | owner == UMUTEX_RB_NOTRECOV) |
| 1015 | return (0); |
| 1016 | } else { |
| 1017 | /* |
| 1018 | * Robust mutex terminated. Kernel duty is to |
| 1019 | * return EOWNERDEAD to the userspace. The |
| 1020 | * umutex.m_flags UMUTEX_NONCONSISTENT is set |
| 1021 | * by the common userspace code. |
| 1022 | */ |
| 1023 | if (owner == UMUTEX_RB_OWNERDEAD) { |
| 1024 | rv = casueword32(&m->m_owner, |
| 1025 | UMUTEX_RB_OWNERDEAD, &owner, |
| 1026 | id | UMUTEX_CONTESTED); |
| 1027 | if (rv == -1) |
| 1028 | return (EFAULT); |
| 1029 | if (rv == 0) { |
| 1030 | MPASS(owner == UMUTEX_RB_OWNERDEAD); |
| 1031 | return (EOWNERDEAD); /* success */ |
| 1032 | } |
| 1033 | MPASS(rv == 1); |
| 1034 | rv = thread_check_susp(td, false); |
| 1035 | if (rv != 0) |
| 1036 | return (rv); |
| 1037 | continue; |
| 1038 | } |
| 1039 | if (owner == UMUTEX_RB_NOTRECOV) |
| 1040 | return (ENOTRECOVERABLE); |
| 1041 | |
| 1042 | /* |
| 1043 | * Try the uncontested case. This should be |
| 1044 | * done in userland. |
no test coverage detected