Date: Fri, 5 Nov 2010 06:42:30 +0000 (UTC) From: David Xu <davidxu@FreeBSD.org> To: src-committers@freebsd.org, svn-src-user@freebsd.org Subject: svn commit: r214825 - user/davidxu/libthr/lib/libthr/thread Message-ID: <201011050642.oA56gUcG087255@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: davidxu Date: Fri Nov 5 06:42:30 2010 New Revision: 214825 URL: http://svn.freebsd.org/changeset/base/214825 Log: Merge mutex link code from libthr.user_requeue. Now following the change in kernel, we use UMUTEX_SIMPLE bit flag to avoid use thread id from process-private mutex, so we don't need to link mutex into list, this saves some cycles. Not that for priority-protect mutex, we still need to link it, because we should restore correct priority after unlocking a such kind of mutex. Also the priority-inhertied mutex needs to be linked, because we still use thread ID as lock-word. The simplest mutex is now a bit faster then before. Modified: user/davidxu/libthr/lib/libthr/thread/thr_create.c user/davidxu/libthr/lib/libthr/thread/thr_init.c user/davidxu/libthr/lib/libthr/thread/thr_mutex.c user/davidxu/libthr/lib/libthr/thread/thr_private.h Modified: user/davidxu/libthr/lib/libthr/thread/thr_create.c ============================================================================== --- user/davidxu/libthr/lib/libthr/thread/thr_create.c Fri Nov 5 06:39:38 2010 (r214824) +++ user/davidxu/libthr/lib/libthr/thread/thr_create.c Fri Nov 5 06:42:30 2010 (r214825) @@ -111,8 +111,7 @@ _pthread_create(pthread_t * thread, cons new_thread->cancel_enable = 1; new_thread->cancel_async = 0; /* Initialize the mutex queue: */ - TAILQ_INIT(&new_thread->mutexq); - TAILQ_INIT(&new_thread->pp_mutexq); + _thr_mutex_link_init(new_thread); /* Initialise hooks in the thread structure: */ if (new_thread->attr.suspend == THR_CREATE_SUSPENDED) { Modified: user/davidxu/libthr/lib/libthr/thread/thr_init.c ============================================================================== --- user/davidxu/libthr/lib/libthr/thread/thr_init.c Fri Nov 5 06:39:38 2010 (r214824) +++ user/davidxu/libthr/lib/libthr/thread/thr_init.c Fri Nov 5 06:42:30 2010 (r214825) @@ -89,13 +89,15 @@ struct pthread_attr _pthread_attr_defaul struct pthread_mutex_attr _pthread_mutexattr_default = { .m_type = PTHREAD_MUTEX_DEFAULT, .m_protocol = PTHREAD_PRIO_NONE, - .m_ceiling = 0 + .m_ceiling = 0, + .m_pshared = 0 }; struct pthread_mutex_attr _pthread_mutexattr_adaptive_default = { .m_type = PTHREAD_MUTEX_ADAPTIVE_NP, .m_protocol = PTHREAD_PRIO_NONE, - .m_ceiling = 0 + .m_ceiling = 0, + .m_pshared = 0 }; /* Default condition variable attributes: */ @@ -412,8 +414,7 @@ init_main_thread(struct pthread *thread) thr_set_name(thread->tid, "initial thread"); /* Initialize the mutex queue: */ - TAILQ_INIT(&thread->mutexq); - TAILQ_INIT(&thread->pp_mutexq); + _thr_mutex_link_init(thread); thread->state = PS_RUNNING; Modified: user/davidxu/libthr/lib/libthr/thread/thr_mutex.c ============================================================================== --- user/davidxu/libthr/lib/libthr/thread/thr_mutex.c Fri Nov 5 06:39:38 2010 (r214824) +++ user/davidxu/libthr/lib/libthr/thread/thr_mutex.c Fri Nov 5 06:42:30 2010 (r214825) @@ -41,29 +41,21 @@ #include <sys/queue.h> #include <pthread.h> #include <pthread_np.h> +#include <sys/mman.h> #include "un-namespace.h" #include "thr_private.h" -#if defined(_PTHREADS_INVARIANTS) -#define MUTEX_INIT_LINK(m) do { \ - (m)->m_qe.tqe_prev = NULL; \ - (m)->m_qe.tqe_next = NULL; \ -} while (0) -#define MUTEX_ASSERT_IS_OWNED(m) do { \ - if (__predict_false((m)->m_qe.tqe_prev == NULL))\ - PANIC("mutex is not on list"); \ -} while (0) -#define MUTEX_ASSERT_NOT_OWNED(m) do { \ - if (__predict_false((m)->m_qe.tqe_prev != NULL || \ - (m)->m_qe.tqe_next != NULL)) \ - PANIC("mutex is on list"); \ -} while (0) -#else -#define MUTEX_INIT_LINK(m) -#define MUTEX_ASSERT_IS_OWNED(m) -#define MUTEX_ASSERT_NOT_OWNED(m) -#endif +#define CHECK_AND_INIT_MUTEX \ + if (__predict_false((m = *mutex) <= THR_MUTEX_DESTROYED)) { \ + if (m == THR_MUTEX_DESTROYED) \ + return (EINVAL); \ + int error; \ + error = init_static(_get_curthread(), mutex); \ + if (error) \ + return (error); \ + m = *mutex; \ + } /* * For adaptive mutexes, how many times to spin doing trylock2 @@ -95,6 +87,8 @@ static int mutex_self_lock(pthread_mutex static int mutex_unlock_common(pthread_mutex_t *); static int mutex_lock_sleep(struct pthread *, pthread_mutex_t, const struct timespec *); +static void enqueue_mutex(struct pthread *, struct pthread_mutex *); +static void dequeue_mutex(struct pthread *, struct pthread_mutex *); __weak_reference(__pthread_mutex_init, pthread_mutex_init); __strong_reference(__pthread_mutex_init, _pthread_mutex_init); @@ -146,16 +140,16 @@ mutex_init(pthread_mutex_t *mutex, return (ENOMEM); pmutex->m_type = attr->m_type; - pmutex->m_owner = NULL; + pmutex->m_ownertd = NULL; pmutex->m_count = 0; pmutex->m_refcount = 0; pmutex->m_spinloops = 0; pmutex->m_yieldloops = 0; - MUTEX_INIT_LINK(pmutex); switch(attr->m_protocol) { case PTHREAD_PRIO_NONE: pmutex->m_lock.m_owner = UMUTEX_UNOWNED; - pmutex->m_lock.m_flags = 0; + if (attr->m_pshared == 0) + pmutex->m_lock.m_flags |= UMUTEX_SIMPLE; break; case PTHREAD_PRIO_INHERIT: pmutex->m_lock.m_owner = UMUTEX_UNOWNED; @@ -164,10 +158,13 @@ mutex_init(pthread_mutex_t *mutex, case PTHREAD_PRIO_PROTECT: pmutex->m_lock.m_owner = UMUTEX_CONTESTED; pmutex->m_lock.m_flags = UMUTEX_PRIO_PROTECT; + if (attr->m_pshared == 0) + pmutex->m_lock.m_flags |= UMUTEX_SIMPLE; pmutex->m_lock.m_ceilings[0] = attr->m_ceiling; break; } - + if (attr->m_pshared != 0) + pmutex->m_lock.m_flags |= USYNC_PROCESS_SHARED; if (pmutex->m_type == PTHREAD_MUTEX_ADAPTIVE_NP) { pmutex->m_spinloops = _thr_spinloops ? _thr_spinloops: MUTEX_ADAPTIVE_SPINS; @@ -196,17 +193,6 @@ init_static(struct pthread *thread, pthr return (ret); } -static void -set_inherited_priority(struct pthread *curthread, struct pthread_mutex *m) -{ - struct pthread_mutex *m2; - - m2 = TAILQ_LAST(&curthread->pp_mutexq, mutex_queue); - if (m2 != NULL) - m->m_lock.m_ceilings[1] = m2->m_lock.m_ceilings[0]; - else - m->m_lock.m_ceilings[1] = -1; -} int __pthread_mutex_init(pthread_mutex_t *mutex, @@ -236,22 +222,14 @@ _pthread_mutex_init_calloc_cb(pthread_mu void _mutex_fork(struct pthread *curthread) { - struct pthread_mutex *m; + struct mutex_link *ml; /* - * Fix mutex ownership for child process. - * note that process shared mutex should not - * be inherited because owner is forking thread - * which is in parent process, they should be - * removed from the owned mutex list, current, - * process shared mutex is not supported, so I - * am not worried. + * Fix mutex ownership for child process. Only PI mutex need to + * be changed, because we still use TID as lock-word. */ - - TAILQ_FOREACH(m, &curthread->mutexq, m_qe) - m->m_lock.m_owner = TID(curthread); - TAILQ_FOREACH(m, &curthread->pp_mutexq, m_qe) - m->m_lock.m_owner = TID(curthread) | UMUTEX_CONTESTED; + TAILQ_FOREACH(ml, &curthread->pi_mutexq, qe) + ml->mutexp->m_lock.m_owner = TID(curthread); } int @@ -266,11 +244,11 @@ _pthread_mutex_destroy(pthread_mutex_t * } else if (m == THR_MUTEX_DESTROYED) { ret = EINVAL; } else { - if (m->m_owner != NULL || m->m_refcount != 0) { + if ((m->m_lock.m_owner & UMUTEX_OWNER_MASK) != 0 || + m->m_refcount != 0) { ret = EBUSY; } else { *mutex = THR_MUTEX_DESTROYED; - MUTEX_ASSERT_NOT_OWNED(m); free(m); ret = 0; } @@ -279,28 +257,6 @@ _pthread_mutex_destroy(pthread_mutex_t * return (ret); } -#define ENQUEUE_MUTEX(curthread, m) \ - do { \ - (m)->m_owner = curthread; \ - /* Add to the list of owned mutexes: */ \ - MUTEX_ASSERT_NOT_OWNED((m)); \ - if (((m)->m_lock.m_flags & UMUTEX_PRIO_PROTECT) == 0) \ - TAILQ_INSERT_TAIL(&curthread->mutexq, (m), m_qe);\ - else \ - TAILQ_INSERT_TAIL(&curthread->pp_mutexq, (m), m_qe);\ - } while (0) - -#define CHECK_AND_INIT_MUTEX \ - if (__predict_false((m = *mutex) <= THR_MUTEX_DESTROYED)) { \ - if (m == THR_MUTEX_DESTROYED) \ - return (EINVAL); \ - int ret; \ - ret = init_static(_get_curthread(), mutex); \ - if (ret) \ - return (ret); \ - m = *mutex; \ - } - static int mutex_trylock_common(pthread_mutex_t *mutex) { @@ -309,15 +265,24 @@ mutex_trylock_common(pthread_mutex_t *mu uint32_t id; int ret; - id = TID(curthread); + if ((m->m_lock.m_flags & UMUTEX_SIMPLE) != 0) + id = UMUTEX_SIMPLE_OWNER; + else + id = TID(curthread); if (m->m_private) THR_CRITICAL_ENTER(curthread); ret = _thr_umutex_trylock(&m->m_lock, id); if (__predict_true(ret == 0)) { - ENQUEUE_MUTEX(curthread, m); - } else if (m->m_owner == curthread) { - ret = mutex_self_trylock(m); - } /* else {} */ + enqueue_mutex(curthread, m); + } else { + if ((m->m_lock.m_flags & UMUTEX_SIMPLE) != 0) { + if (m->m_ownertd == curthread) + ret = mutex_self_trylock(m); + } else { + if ((m->m_lock.m_owner & UMUTEX_OWNER_MASK) == id) + ret = mutex_self_trylock(m); + } + } if (ret && m->m_private) THR_CRITICAL_LEAVE(curthread); return (ret); @@ -341,10 +306,16 @@ mutex_lock_sleep(struct pthread *curthre int count; int ret; - if (m->m_owner == curthread) - return mutex_self_lock(m, abstime); - id = TID(curthread); + if ((m->m_lock.m_flags & UMUTEX_SIMPLE) != 0) { + if (m->m_ownertd == curthread) + return mutex_self_lock(m, abstime); + id = UMUTEX_SIMPLE_OWNER; + } else { + id = TID(curthread); + if ((m->m_lock.m_owner & UMUTEX_OWNER_MASK) == id) + return mutex_self_lock(m, abstime); + } /* * For adaptive mutexes, spin for a bit in the expectation * that if the application requests this mutex type then @@ -362,7 +333,7 @@ mutex_lock_sleep(struct pthread *curthre count = m->m_spinloops; while (count--) { owner = m->m_lock.m_owner; - if ((owner & ~UMUTEX_CONTESTED) == 0) { + if ((owner & UMUTEX_OWNER_MASK) == 0) { if (atomic_cmpset_acq_32(&m->m_lock.m_owner, owner, id|owner)) { ret = 0; goto done; @@ -396,7 +367,7 @@ sleep_in_kernel: } done: if (ret == 0) - ENQUEUE_MUTEX(curthread, m); + enqueue_mutex(curthread, m); return (ret); } @@ -406,12 +377,18 @@ mutex_lock_common(struct pthread_mutex * const struct timespec *abstime, int cvattach) { struct pthread *curthread = _get_curthread(); + uint32_t id; int ret; + if ((m->m_lock.m_flags & UMUTEX_SIMPLE) != 0) + id = UMUTEX_SIMPLE_OWNER; + else + id = TID(curthread); + if (m->m_private && !cvattach) THR_CRITICAL_ENTER(curthread); - if (_thr_umutex_trylock2(&m->m_lock, TID(curthread)) == 0) { - ENQUEUE_MUTEX(curthread, m); + if (_thr_umutex_trylock2(&m->m_lock, id) == 0) { + enqueue_mutex(curthread, m); ret = 0; } else { ret = mutex_lock_sleep(curthread, m, abstime); @@ -551,7 +528,7 @@ mutex_self_lock(struct pthread_mutex *m, int _mutex_owned(struct pthread *curthread, const pthread_mutex_t *mutex) { - struct pthread_mutex *m; + struct pthread_mutex *m; m = *mutex; if (__predict_false(m <= THR_MUTEX_DESTROYED)) { @@ -559,11 +536,17 @@ _mutex_owned(struct pthread *curthread, return (EINVAL); return (EPERM); } + /* * Check if the running thread is not the owner of the mutex. */ - if (__predict_false(m->m_owner != curthread)) - return (EPERM); + if ((m->m_lock.m_flags & UMUTEX_SIMPLE) != 0) { + if (__predict_false(m->m_ownertd != curthread)) + return (EPERM); + } else { + if ((m->m_lock.m_owner & UMUTEX_OWNER_MASK) != TID(curthread)) + return (EPERM); + } return (0); } @@ -580,22 +563,16 @@ mutex_unlock_common(pthread_mutex_t *mut m = *mutex; - id = TID(curthread); if (__predict_false( m->m_type == PTHREAD_MUTEX_RECURSIVE && m->m_count > 0)) { m->m_count--; } else { - m->m_owner = NULL; - /* Remove the mutex from the threads queue. */ - MUTEX_ASSERT_IS_OWNED(m); - if (__predict_true((m->m_lock.m_flags & UMUTEX_PRIO_PROTECT) == 0)) - TAILQ_REMOVE(&curthread->mutexq, m, m_qe); - else { - TAILQ_REMOVE(&curthread->pp_mutexq, m, m_qe); - set_inherited_priority(curthread, m); - } - MUTEX_INIT_LINK(m); + if ((m->m_lock.m_flags & UMUTEX_SIMPLE) != 0) + id = UMUTEX_SIMPLE_OWNER; + else + id = TID(curthread); + dequeue_mutex(curthread, m); _thr_umutex_unlock(&m->m_lock, id); } if (m->m_private) @@ -623,6 +600,7 @@ _mutex_cv_unlock(pthread_mutex_t *mutex, { struct pthread *curthread = _get_curthread(); struct pthread_mutex *m; + uint32_t id; int err; if ((err = _mutex_owned(curthread, mutex)) != 0) @@ -636,17 +614,12 @@ _mutex_cv_unlock(pthread_mutex_t *mutex, *count = m->m_count; m->m_refcount++; m->m_count = 0; - m->m_owner = NULL; - /* Remove the mutex from the threads queue. */ - MUTEX_ASSERT_IS_OWNED(m); - if (__predict_true((m->m_lock.m_flags & UMUTEX_PRIO_PROTECT) == 0)) - TAILQ_REMOVE(&curthread->mutexq, m, m_qe); - else { - TAILQ_REMOVE(&curthread->pp_mutexq, m, m_qe); - set_inherited_priority(curthread, m); - } - MUTEX_INIT_LINK(m); - _thr_umutex_unlock(&m->m_lock, TID(curthread)); + dequeue_mutex(curthread, m); + if ((m->m_lock.m_flags & UMUTEX_SIMPLE) != 0) + id = UMUTEX_SIMPLE_OWNER; + else + id = TID(curthread); + _thr_umutex_unlock(&m->m_lock, id); if (m->m_private) THR_CRITICAL_LEAVE(curthread); @@ -661,7 +634,7 @@ _mutex_cv_attach(pthread_mutex_t *mutex, int ret; m = *mutex; - ENQUEUE_MUTEX(curthread, m); + enqueue_mutex(curthread, m); m->m_refcount--; m->m_count += count; return (ret); @@ -685,16 +658,7 @@ _mutex_cv_detach(pthread_mutex_t *mutex, *count = m->m_count; m->m_refcount++; m->m_count = 0; - m->m_owner = NULL; - /* Remove the mutex from the threads queue. */ - MUTEX_ASSERT_IS_OWNED(m); - if (__predict_true((m->m_lock.m_flags & UMUTEX_PRIO_PROTECT) == 0)) - TAILQ_REMOVE(&curthread->mutexq, m, m_qe); - else { - TAILQ_REMOVE(&curthread->pp_mutexq, m, m_qe); - set_inherited_priority(curthread, m); - } - MUTEX_INIT_LINK(m); + dequeue_mutex(curthread, m); return (0); } @@ -722,7 +686,8 @@ _pthread_mutex_setprioceiling(pthread_mu int ceiling, int *old_ceiling) { struct pthread *curthread = _get_curthread(); - struct pthread_mutex *m, *m1, *m2; + struct mutex_link *ml, *ml1, *ml2; + struct pthread_mutex *m; int ret; m = *mutex; @@ -733,21 +698,26 @@ _pthread_mutex_setprioceiling(pthread_mu ret = __thr_umutex_set_ceiling(&m->m_lock, ceiling, old_ceiling); if (ret != 0) return (ret); - - if (m->m_owner == curthread) { - MUTEX_ASSERT_IS_OWNED(m); - m1 = TAILQ_PREV(m, mutex_queue, m_qe); - m2 = TAILQ_NEXT(m, m_qe); - if ((m1 != NULL && m1->m_lock.m_ceilings[0] > (u_int)ceiling) || - (m2 != NULL && m2->m_lock.m_ceilings[0] < (u_int)ceiling)) { - TAILQ_REMOVE(&curthread->pp_mutexq, m, m_qe); - TAILQ_FOREACH(m2, &curthread->pp_mutexq, m_qe) { - if (m2->m_lock.m_ceilings[0] > (u_int)ceiling) { - TAILQ_INSERT_BEFORE(m2, m, m_qe); + if (((m->m_lock.m_flags & UMUTEX_SIMPLE) && (m->m_ownertd == curthread)) || + (m->m_lock.m_owner & UMUTEX_OWNER_MASK) == TID(curthread)) { + TAILQ_FOREACH(ml, &curthread->pp_mutexq, qe) { + if (ml->mutexp == m) + break; + } + if (ml == NULL) /* howto ? */ + return (0); + ml1 = TAILQ_PREV(ml, mutex_link_list, qe); + ml2 = TAILQ_NEXT(ml, qe); + if ((ml1 != NULL && ml1->mutexp->m_lock.m_ceilings[0] > (u_int)ceiling) || + (ml2 != NULL && ml2->mutexp->m_lock.m_ceilings[0] < (u_int)ceiling)) { + TAILQ_REMOVE(&curthread->pp_mutexq, ml, qe); + TAILQ_FOREACH(ml2, &curthread->pp_mutexq, qe) { + if (ml2->mutexp->m_lock.m_ceilings[0] > (u_int)ceiling) { + TAILQ_INSERT_BEFORE(ml2, ml, qe); return (0); } } - TAILQ_INSERT_TAIL(&curthread->pp_mutexq, m, m_qe); + TAILQ_INSERT_TAIL(&curthread->pp_mutexq, ml, qe); } } return (0); @@ -800,10 +770,128 @@ __pthread_mutex_setyieldloops_np(pthread int _pthread_mutex_isowned_np(pthread_mutex_t *mutex) { - struct pthread_mutex *m; + return (_mutex_owned(_get_curthread(), mutex) == 0); +} - m = *mutex; - if (m <= THR_MUTEX_DESTROYED) - return (0); - return (m->m_owner == _get_curthread()); +void +_thr_mutex_link_init(struct pthread *td) +{ + TAILQ_INIT(&td->mutex_link_freeq); + TAILQ_INIT(&td->mutex_link_pages); + TAILQ_INIT(&td->pi_mutexq); + TAILQ_INIT(&td->pp_mutexq); +} + +struct mutex_link * +_thr_mutex_link_alloc(void) +{ + struct pthread *curthread = _get_curthread(); + struct mutex_link *p; + unsigned i; + + p = TAILQ_FIRST(&curthread->mutex_link_freeq); + if (p == NULL) { + struct mutex_link *pp = (struct mutex_link *)mmap(NULL, + _thr_page_size, PROT_READ|PROT_WRITE, MAP_ANON, -1, 0); + for (i = 2; i < _thr_page_size/sizeof(struct mutex_link); ++i) + TAILQ_INSERT_TAIL(&curthread->mutex_link_freeq, &pp[i], qe); + pp[0].mutexp = (struct pthread_mutex *)pp; /* the page address */ + TAILQ_INSERT_HEAD(&curthread->mutex_link_pages, &pp[0], qe); + p = &pp[1]; + } + _thread_printf(2, "%s alloc p=%x\n", __func__, p); + return (p); +} + +void +_thr_mutex_link_free(struct mutex_link *ml) +{ + struct pthread *curthread = _get_curthread(); + + TAILQ_INSERT_TAIL(&curthread->mutex_link_freeq, ml, qe); +} + +void +_thr_mutex_link_exit(struct pthread *curthread) +{ + struct mutex_link *ml, *ml2; + + TAILQ_FOREACH_SAFE(ml, &curthread->mutex_link_pages, qe, ml2) { + TAILQ_REMOVE(&curthread->mutex_link_pages, ml, qe); + munmap(ml->mutexp, _thr_page_size); + } + TAILQ_INIT(&curthread->mutex_link_freeq); +} + +static void +set_inherited_priority(struct pthread *curthread, struct pthread_mutex *m) +{ + struct mutex_link *ml2; + + ml2 = TAILQ_LAST(&curthread->pp_mutexq, mutex_link_list); + if (ml2 != NULL) + m->m_lock.m_ceilings[1] = ml2->mutexp->m_lock.m_ceilings[0]; + else + m->m_lock.m_ceilings[1] = -1; +} + +static void +enqueue_mutex(struct pthread *curthread, struct pthread_mutex *m) +{ + struct mutex_link *ml; + + if ((m->m_lock.m_flags & USYNC_PROCESS_SHARED) == 0) + m->m_ownertd = curthread; + + /* + * For PP mutex, we should restore previous priority after a PP + * mutex is unlocked, so we should remember every PP mutex. + */ + if ((m->m_lock.m_flags & UMUTEX_PRIO_PROTECT) != 0) { + ml = _thr_mutex_link_alloc(); + ml->mutexp = m; + TAILQ_INSERT_TAIL(&curthread->pp_mutexq, ml, qe); + } else if ((m->m_lock.m_flags & (UMUTEX_PRIO_INHERIT | + USYNC_PROCESS_SHARED)) == UMUTEX_PRIO_INHERIT) { + /* + * To make unlocking after fork() work, we need to link it, + * because we still use TID as lock-word for PI mutex. + * However, processs-shared mutex only has one copy, it should + * not be unlockable for child process, so we don't link it. + */ + if ((m->m_lock.m_flags & USYNC_PROCESS_SHARED) == 0) { + ml = _thr_mutex_link_alloc(); + ml->mutexp = m; + TAILQ_INSERT_TAIL(&curthread->pi_mutexq, ml, qe); + } + } +} + +static void +dequeue_mutex(struct pthread *curthread, struct pthread_mutex *m) +{ + struct mutex_link *ml; + + if ((m->m_lock.m_flags & USYNC_PROCESS_SHARED) == 0) + m->m_ownertd = NULL; + + if ((m->m_lock.m_flags & UMUTEX_PRIO_PROTECT) != 0) { + TAILQ_FOREACH(ml, &curthread->pp_mutexq, qe) { + if (ml->mutexp == m) { + TAILQ_REMOVE(&curthread->pp_mutexq, ml, qe); + set_inherited_priority(curthread, m); + _thr_mutex_link_free(ml); + break; + } + } + } else if ((m->m_lock.m_flags & (UMUTEX_PRIO_INHERIT | + USYNC_PROCESS_SHARED)) == UMUTEX_PRIO_INHERIT) { + TAILQ_FOREACH(ml, &curthread->pi_mutexq, qe) { + if (ml->mutexp == m) { + TAILQ_REMOVE(&curthread->pi_mutexq, ml, qe); + _thr_mutex_link_free(ml); + break; + } + } + } } Modified: user/davidxu/libthr/lib/libthr/thread/thr_private.h ============================================================================== --- user/davidxu/libthr/lib/libthr/thread/thr_private.h Fri Nov 5 06:39:38 2010 (r214824) +++ user/davidxu/libthr/lib/libthr/thread/thr_private.h Fri Nov 5 06:42:30 2010 (r214825) @@ -82,7 +82,7 @@ struct mutex_link { struct pthread_mutex *mutexp; }; -TAILQ_HEAD(mutex_queue, pthread_mutex); +TAILQ_HEAD(mutex_link_list, mutex_link); /* Signal to do cancellation */ #define SIGCANCEL 32 @@ -141,32 +141,23 @@ TAILQ_HEAD(mutex_queue, pthread_mutex); #define THR_RWLOCK_DESTROYED ((struct pthread_rwlock *)1) struct pthread_mutex { - /* - * Lock for accesses to this structure. - */ - struct umutex m_lock; - enum pthread_mutextype m_type; - struct pthread *m_owner; - int m_count; - int m_refcount; - int m_spinloops; - int m_yieldloops; - int m_private; - /* - * Link for all mutexes a thread currently owns. - */ - TAILQ_ENTRY(pthread_mutex) m_qe; + struct umutex m_lock; + enum pthread_mutextype m_type; + struct pthread *m_ownertd; + int m_count; + int m_refcount; + int m_spinloops; + int m_yieldloops; + int m_private; }; struct pthread_mutex_attr { enum pthread_mutextype m_type; int m_protocol; int m_ceiling; + int m_pshared; }; -#define PTHREAD_MUTEXATTR_STATIC_INITIALIZER \ - { PTHREAD_MUTEX_DEFAULT, PTHREAD_PRIO_NONE, 0, MUTEX_FLAGS_PRIVATE } - struct pthread_cond { struct ucond c_kerncv; /* @@ -450,10 +441,13 @@ struct pthread { #define TLFLAGS_IN_GCLIST 0x0004 /* thread in gc list */ /* Queue of currently owned NORMAL or PRIO_INHERIT type mutexes. */ - struct mutex_queue mutexq; + struct mutex_link_list pi_mutexq; /* Queue of all owned PRIO_PROTECT mutexes. */ - struct mutex_queue pp_mutexq; + struct mutex_link_list pp_mutexq; + + struct mutex_link_list mutex_link_freeq; + struct mutex_link_list mutex_link_pages; void *ret; struct pthread_specific_elem *specific; @@ -756,6 +750,10 @@ int _schedparam_to_rtp(int policy, const void _thread_bp_create(void); void _thread_bp_death(void); int _sched_yield(void); +void _thr_mutex_link_init(struct pthread *); +struct mutex_link *_thr_mutex_link_alloc(void); +void _thr_mutex_link_free(struct mutex_link *); +void _thr_mutex_link_exit(struct pthread *); void _pthread_cleanup_push(void (*)(void *), void *); void _pthread_cleanup_pop(int); @@ -831,10 +829,6 @@ struct dl_phdr_info; void __pthread_cxa_finalize(struct dl_phdr_info *phdr_info); void _thr_tsd_unload(struct dl_phdr_info *phdr_info) __hidden; void _thr_sigact_unload(struct dl_phdr_info *phdr_info) __hidden; - -void _thr_mutex_link_init(void); -struct mutex_link * _thr_mutex_link_alloc(void); -void _thr_mutex_link_free(struct mutex_link *p); __END_DECLS #endif /* !_THR_PRIVATE_H */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201011050642.oA56gUcG087255>