High CPU usage with pthread_mutex_lock, pthread_mutex_unlock, pthead_cond_wait in mutex contention in multiple threads

772 views
Skip to first unread message

驼峰

unread,
Jul 5, 2011, 6:04:26 AM7/5/11
to android-ndk
Hi, All

I run into the following issues.
Firstly, I have two threads and our NDK version is nr5c. I run in
Samsung Nexus S.

Thread A calls Queue.Enqueue and Thread B calls Queue::Dequeue.

Thread A and Thread B are frequently switched (about 150 times /
second). In this case, the CPU time of Queue:Dequeue function is
pretty high after I profile it use the profiler:
http://code.google.com/p/android-ndk-profiler/. It seems that more
than 50% process CPU time is consumed by this function.

I guess when threads are waiting for mutex lock acquisition, it should
not take CPU time. Why the CPU time of this function so high?

Could someone help me clarify it?

Thanks

The code snippet is as following

BOOL
Queue::Enqueue(
int TaskId,
int TaskParam
)
{
QueueItem* pEntry = Alloc();

pEntry->mTaskId = TaskId;
pEntry->mTaskParam = TaskParam;
pEntry->m_Next = NULL;

pthread_mutex_lock(&m_Mutext);
if (m_Tail) {
m_Tail->m_Next = pEntry;
m_Tail = pEntry;
} else {
m_Head = m_Tail = pEntry;
}
pthread_mutex_unlock(&m_Mutext);

pthread_cond_signal(&m_CondVar);
return TRUE;
}

BOOL
Queue::Dequeue(
QueueItem* entry,
uint32_t uCount,
uint32_t* uNumEntriesRemoved
)
{
uint32_t cnt = 0;
QueueItem * pEntry;
int UnixErr = 0;

pthread_mutex_lock(&m_Mutext);
while(1) {
pEntry = m_Head;
while(pEntry && cnt < uCount) {
QueueItem* pNext;
entry[cnt].TaskId = pEntry->mTaskId;
entry[cnt].TaskParam = pEntry->mTaskParam;

pNext = pEntry->m_Next;
Free(pEntry);
pEntry = pNext;
cnt++;
}

m_Head = pEntry;
if (m_Head == NULL) {
m_Tail = NULL;
}

if (cnt > 0) {
break;
}

pthread_cond_wait(&m_CondVar, &m_Mutext);
}

pthread_mutex_unlock(&m_Mutext);
*uNumEntriesRemoved = cnt;
return cnt != 0;
}

Thanks,
-Mike

某因幡

unread,
Jul 5, 2011, 8:37:55 AM7/5/11
to andro...@googlegroups.com
You have mistake in your code.
mutex_lock
cond_signal
mutex_unlock
This is the right sequence.
Wait on a CV will first unlock the mutex and then wait.

2011/7/5 驼峰 <guotu...@gmail.com>

--
You received this message because you are subscribed to the Google Groups "android-ndk" group.
To post to this group, send email to andro...@googlegroups.com.
To unsubscribe from this group, send email to android-ndk...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/android-ndk?hl=en.




--
language: Chinese, Japanese, English

驼峰

unread,
Jul 5, 2011, 9:45:40 PM7/5/11
to android-ndk
Thank for your reply.

Actually, the cond_signal call location doesn't impact the performance
very much. I tried to move it between the lock/unlock, the result is
same.

The typical threading switch sequences are like:

Threading call enqueue
Threading call dequeue
Threading call enqueue
Threading call dequeue
Threading call enqueue
Threading call dequeue
Threading call enqueue
Threading call dequeue
Threading call enqueue
Threading call dequeue
Threading call dequeue
Threading call enqueue
Threading call dequeue
Threading call enqueue
Threading call dequeue

So, I am just wondering two possibilities:
1. the profiler tools has some bugs and it count into the duration in
which threads in blocking state.
2. if the profiler tools result is correct, is it possible that the
frequent threading switch is the root cause of high CPU?

Thanks,
-Mike
Reply all
Reply to author
Forward
0 new messages