1570af302Sopenharmony_ci#include "pthread_impl.h" 2570af302Sopenharmony_ci 3570af302Sopenharmony_ciint __pthread_mutex_trylock_owner(pthread_mutex_t *m) 4570af302Sopenharmony_ci{ 5570af302Sopenharmony_ci int old, own; 6570af302Sopenharmony_ci int type = m->_m_type; 7570af302Sopenharmony_ci pthread_t self = __pthread_self(); 8570af302Sopenharmony_ci int tid = self->tid; 9570af302Sopenharmony_ci 10570af302Sopenharmony_ci old = m->_m_lock; 11570af302Sopenharmony_ci own = old & 0x3fffffff; 12570af302Sopenharmony_ci#ifdef __LITEOS_A__ 13570af302Sopenharmony_ci if (own == tid) { 14570af302Sopenharmony_ci if ((type&PTHREAD_MUTEX_TYPE_MASK) == PTHREAD_MUTEX_RECURSIVE) { 15570af302Sopenharmony_ci if ((unsigned)m->_m_count >= INT_MAX) return EAGAIN; 16570af302Sopenharmony_ci m->_m_count++; 17570af302Sopenharmony_ci return 0; 18570af302Sopenharmony_ci } 19570af302Sopenharmony_ci } 20570af302Sopenharmony_ci#else 21570af302Sopenharmony_ci if (__is_mutex_destroyed(m->_m_type)) 22570af302Sopenharmony_ci __handle_using_destroyed_mutex(m, __FUNCTION__); 23570af302Sopenharmony_ci if (own == tid) { 24570af302Sopenharmony_ci if ((type&8) && m->_m_count<0) { 25570af302Sopenharmony_ci old &= 0x40000000; 26570af302Sopenharmony_ci m->_m_count = 0; 27570af302Sopenharmony_ci goto success; 28570af302Sopenharmony_ci } 29570af302Sopenharmony_ci if ((type&3) == PTHREAD_MUTEX_RECURSIVE) { 30570af302Sopenharmony_ci if ((unsigned)m->_m_count >= INT_MAX) return EAGAIN; 31570af302Sopenharmony_ci m->_m_count++; 32570af302Sopenharmony_ci return 0; 33570af302Sopenharmony_ci } 34570af302Sopenharmony_ci } 35570af302Sopenharmony_ci#endif 36570af302Sopenharmony_ci if (own == 0x3fffffff) return ENOTRECOVERABLE; 37570af302Sopenharmony_ci if (own || (old && !(type & 4))) return EBUSY; 38570af302Sopenharmony_ci 39570af302Sopenharmony_ci if (type & 128) { 40570af302Sopenharmony_ci if (!self->robust_list.off) { 41570af302Sopenharmony_ci self->robust_list.off = (char*)&m->_m_lock-(char *)&m->_m_next; 42570af302Sopenharmony_ci#ifndef __LITEOS_A__ 43570af302Sopenharmony_ci __syscall(SYS_set_robust_list, &self->robust_list, 3*sizeof(long)); 44570af302Sopenharmony_ci#endif 45570af302Sopenharmony_ci } 46570af302Sopenharmony_ci if (m->_m_waiters) tid |= 0x80000000; 47570af302Sopenharmony_ci self->robust_list.pending = &m->_m_next; 48570af302Sopenharmony_ci } 49570af302Sopenharmony_ci tid |= old & 0x40000000; 50570af302Sopenharmony_ci 51570af302Sopenharmony_ci if (a_cas(&m->_m_lock, old, tid) != old) { 52570af302Sopenharmony_ci self->robust_list.pending = 0; 53570af302Sopenharmony_ci#ifndef __LITEOS_A__ 54570af302Sopenharmony_ci if ((type&12)==12 && m->_m_waiters) return ENOTRECOVERABLE; 55570af302Sopenharmony_ci#endif 56570af302Sopenharmony_ci return EBUSY; 57570af302Sopenharmony_ci } 58570af302Sopenharmony_ci 59570af302Sopenharmony_ci#ifndef __LITEOS_A__ 60570af302Sopenharmony_cisuccess: 61570af302Sopenharmony_ci if ((type&8) && m->_m_waiters) { 62570af302Sopenharmony_ci int priv = (type & 128) ^ 128; 63570af302Sopenharmony_ci __syscall(SYS_futex, &m->_m_lock, FUTEX_UNLOCK_PI|priv); 64570af302Sopenharmony_ci self->robust_list.pending = 0; 65570af302Sopenharmony_ci return (type&4) ? ENOTRECOVERABLE : EBUSY; 66570af302Sopenharmony_ci } 67570af302Sopenharmony_ci#endif 68570af302Sopenharmony_ci 69570af302Sopenharmony_ci volatile void *next = self->robust_list.head; 70570af302Sopenharmony_ci m->_m_next = next; 71570af302Sopenharmony_ci m->_m_prev = &self->robust_list.head; 72570af302Sopenharmony_ci if (next != &self->robust_list.head) *(volatile void *volatile *) 73570af302Sopenharmony_ci ((char *)next - sizeof(void *)) = &m->_m_next; 74570af302Sopenharmony_ci self->robust_list.head = &m->_m_next; 75570af302Sopenharmony_ci self->robust_list.pending = 0; 76570af302Sopenharmony_ci 77570af302Sopenharmony_ci if (old) { 78570af302Sopenharmony_ci m->_m_count = 0; 79570af302Sopenharmony_ci return EOWNERDEAD; 80570af302Sopenharmony_ci } 81570af302Sopenharmony_ci 82570af302Sopenharmony_ci return 0; 83570af302Sopenharmony_ci} 84570af302Sopenharmony_ci 85570af302Sopenharmony_ciint __pthread_mutex_trylock(pthread_mutex_t *m) 86570af302Sopenharmony_ci{ 87570af302Sopenharmony_ci if ((m->_m_type&15) == PTHREAD_MUTEX_NORMAL) 88570af302Sopenharmony_ci return a_cas(&m->_m_lock, 0, EBUSY) & EBUSY; 89570af302Sopenharmony_ci return __pthread_mutex_trylock_owner(m); 90570af302Sopenharmony_ci} 91570af302Sopenharmony_ci 92570af302Sopenharmony_ciweak_alias(__pthread_mutex_trylock, pthread_mutex_trylock); 93