# pThreads



## Rohan Kurane (Jan 28, 2015)

I am new to FreeBSD and have a question regarding how pThreads work. Mainly, the m_qe structure within the pthread_mutex_t struct type.

```
m_qe = {
    tqe_next = 0x80555d330,
    tqe_prev = 0x0
   }
```

How are the two fields m_qe.tqe_next and m_qe.tqe_prev used and set? The MUTEX_ASSERT_IS_OWNED and MUTEX_ASSERT_IS_NOT_OWNED macros in src/freebsd-c/lib/libthr/thread/thr_mutex.c check these fields to determine if it needs to panic.

Where and how are these two fields used and set?

Thank you.


----------



## worldi (Jan 28, 2015)

Looks like they are read/modified by the macros provided in sys/queue.h (see queue(3) for details). So you might want to search for `TAILQ_INSERT_TAIL(..., m_qe)` and `TAILQ_REMOVE(..., m_qe)`.

This link might come handy.


----------



## Rohan Kurane (Jan 28, 2015)

Thanks worldi. I see those macros used in thr_mutex.c, but for the TAILQ_HEAD &curthread->mutexq and TAIL_HEAD &curthread->pp_mutexq. The curthread->mutexq and curthread_pp_mutexq are the list of mutexes owned by a specific thread in the pthread structure. My question was more oriented towards the pthread_mutex_t structure itself and m_qe structure within it. See below..


```
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;

/*
  * Link for all mutexes a thread currently owns.
  */
TAILQ_ENTRY(pthread_mutex) m_qe;
```

The comment above says it is a list of all mutexes a thread currently owns. This is a different list from the curthread->mutexq and curthread->pp_mutexq structures that the TAILQ_INSERT and TAILQ_REMOVE in thr_mutex.c work on. I do not see an operation on the m_qe struct in the pthread_mutex structure. Any idea where that is done ?


----------



## worldi (Jan 28, 2015)

Rohan Kurane said:


> The comment above says it is a list of all mutexes a thread currently owns.



Note that it says it's a *link*, not a list. 

Take a look at the `ENQUEUE_MUTEX` and `DEQUEUE_MUTEX` macros (starting at line 281 on my box [1]): this is where the mutex is add to/removed from either &curthread->mutexq or &curthread->pp_mutexq.


[1] the OpenGrok links you've posted are not publicly available so your source base might differ.


----------



## Rohan Kurane (Jan 28, 2015)

The opengrok code is pretty similar to what you have in the link. The ENQUEUE_MUTEX and DEQUEUE_MUTEX as you mentioned adds and removes a mutex from the curthread structure. I do not see anywhere in the freebsdFreeBSD library where we do the add/remove from the pthread_mutex_t structure. Here is an example -

```
$15 = (pthread_mutex_t) 0x803356380
(gdb) p *$15
$16 = {
  m_lock = {
    m_owner = 100586,
    m_flags = 0,
    m_ceilings = {0, 0},
    m_spare = {0, 0, 0, 0}
  },
  m_type = PTHREAD_MUTEX_RECURSIVE,
  m_owner = 0x803212d40,
  m_count = 0,
  m_refcount = 0,
  m_spinloops = 0,
  m_yieldloops = 0,
  m_qe = {
    tqe_next = 0x80555d330,            --> Where and when is this set ?
    tqe_prev = 0x0
  }
}
```


----------



## worldi (Jan 28, 2015)

Rohan Kurane said:


> ```
> m_qe = {
> tqe_next = 0x80555d330,            --> Where and when is this set ?
> tqe_prev = 0x0
> ...



The only place where tqe_next is set to a non-NULL value seems to be _pthread_mutex_setprioceiling: 

```
...
TAILQ_INSERT_BEFORE(m2, m, m_qe);
...
```


----------



## Rohan Kurane (Jan 29, 2015)

Has anyone seen any panics similar to "mutex is on list" or "mutex is not on list" ?


----------

