Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID:
 <SE1P216MB24848C0A0BDF191A264340509EB42@SE1P216MB2484.KORP216.PROD.OUTLOOK.COM>
Date: Fri, 26 Jul 2024 06:22:50 +0000
From: JinCheng Li <naiveli233@...look.com>
To: musl <musl@...ts.openwall.com>
Subject: Possible unfair scenarios in pthread_mutex_unlock

Hi

I have two questions in pthread_mutex_unlock.

  1.
Why we need a vmlock in only pshared mutex, not in other private mutex?
  2.
For pshared mutex, after swap _m_lock to unlock state, we need to wait for vmunlock before wake other waiters. During this period, if someone trylocks this pshared lock, queue jumping may occur. Is this unfair to the preious waiters? They may have to wait longer to get woken up. This can cause performance issues, do we have any good way to avoid this?

int __pthread_mutex_unlock(pthread_mutex_t *m)
{
    pthread_t self;
    int waiters = m->_m_waiters;
    int cont;
    int type = m->_m_type & 15;
    int priv = (m->_m_type & 128) ^ 128;
    int new = 0;
    int old;

    if (type != PTHREAD_MUTEX_NORMAL) {
        self = __pthread_self();
        old = m->_m_lock;
        int own = old & 0x3fffffff;
        if (own != self->tid)
            return EPERM;
        if ((type&3) == PTHREAD_MUTEX_RECURSIVE && m->_m_count)
            return m->_m_count--, 0;
        if ((type&4) && (old&0x40000000))
            new = 0x7fffffff;
        if (!priv) {
            self->robust_list.pending = &m->_m_next;
            __vm_lock(); // why need lock only here?
        }
        volatile void *prev = m->_m_prev;
        volatile void *next = m->_m_next;
        *(volatile void *volatile *)prev = next;
        if (next != &self->robust_list.head) *(volatile void *volatile *)
            ((char *)next - sizeof(void *)) = prev;
    }
    if (type&8) {
        if (old<0 || a_cas(&m->_m_lock, old, new)!=old) {
            if (new) a_store(&m->_m_waiters, -1);
            __syscall(SYS_futex, &m->_m_lock, FUTEX_UNLOCK_PI|priv);
        }
        cont = 0;
        waiters = 0;
    } else {
        cont = a_swap(&m->_m_lock, new);
    }
    if (type != PTHREAD_MUTEX_NORMAL && !priv) {
        self->robust_list.pending = 0;
        __vm_unlock(); // queue jumping caused by trylock
    }
    if (waiters || cont<0)
        __wake(&m->_m_lock, 1, priv);
    return 0;
}

Li

Content of type "text/html" skipped

Powered by blists - more mailing lists

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.