Girish wrote:
Hi,
One of our threaded process is consuming CPU constantly. It is seen that it is
calling the time,lwp_park and lwp_unpark continuously.
The logic of the code is explained below
Thread A Thread B,C,D,E,...(10 threads)
acquire mutex
queue is empty
cond_wait
acquire mutex
add item N
release mutex
cond_broadcast
queue is not empty
pop item N from queue
release mutex
process item N
acquire mutex
queue is empty
cond_wait
Can you try the test case below? In case the formatting
is disturbed by the mailer, a clean copy is at:
http://home.comcast.net/~jdmartin99/cvbroadcast.c
I'm not getting the lwp syscalls, so please modify it with
the correct thread, mutex and cv attributies.
The number of threads, tasks and whether to use cv_signal
or cv_broadcast are command line options.
rug...@tecram10:~/cvbroadcast$ cc -mt -O cvbroadcast.c
rug...@tecram10:~/cvbroadcast$ ./a.out -help
usage: ./a.out num-threads num-tasks use-broadcast
rug...@tecram10:~/cvbroadcast$ cat cvbroadcast.c
#include <stdlib.h>
#include <stdio.h>
#include <thread.h>
#include <synch.h>
static mutex_t mutex;
static cond_t cv;
static volatile int task;
static uint64_t *processed;
void *
task_thread(void *arg)
{
int slot = (int)arg;
if (mutex_lock(&mutex) != 0) {
fprintf(stderr, "task_thread: couldn't lock mutex\n");
return ((void *)-1);
}
while (task != -1) {
/* queue is not empty */
while (task > 0) {
/* pop item N from queue */
task--;
/* release mutex */
if (mutex_unlock(&mutex) != 0) {
fprintf(stderr,
"task_thread: couldn't unlock mutex\n");
return ((void *)-1);
}
/* process item N */
processed[slot]++;
/* acquire mutex */
if (mutex_lock(&mutex) != 0) {
fprintf(stderr,
"task_thread: couldn't lock mutex\n");
return ((void *)-1);
}
}
if (cond_wait(&cv, &mutex) != 0) {
fprintf(stderr, "task_thread: cond_wait failed\n");
(void)mutex_unlock(&mutex);
return ((void *)-1);
}
}
if (mutex_unlock(&mutex) != 0) {
fprintf(stderr, "task_thread: couldn't unlock mutex\n");
return ((void *)-1);
}
return ((void *)0);
}
int
main(int argc, char *argv[], char *envp[])
{
int num_threads;
int num_tasks;
int use_broadcast;
thread_t *tids;
int i;
if (argc != 4) {
fprintf(stderr,
"usage: %s num-threads num-tasks use-broadcast\n", argv[0]);
return (1);
}
num_threads = atoi(argv[1]);
num_tasks = atoi(argv[2]);
use_broadcast = atoi(argv[3]);
if ((processed = (uint64_t *)calloc(num_threads,
sizeof(processed[0]))) == NULL) {
perror("processed array");
return (1);
}
if ((tids = (thread_t *)calloc(num_threads,
sizeof(thread_t))) == NULL) {
perror("processed array");
return (1);
}
if (mutex_init(&mutex, USYNC_PROCESS, NULL) != 0) {
perror("mutex initialization");
return (1);
}
if (cond_init(&cv, USYNC_PROCESS, NULL) != 0) {
perror("cv initialization");
return (1);
}
fprintf(stdout,
"num_threads = %d, num_tasks = %d, use_broadcast = %d\n",
num_threads, num_tasks, use_broadcast);
task = 0;
for (i=0; i<num_threads; i++) {
if (thr_create(NULL, 0, task_thread, (void *)i, 0, &tids[i])
!= 0) {
perror("creating thread");
return (1);
}
}
for (i=0; i<num_tasks; i++) {
if (mutex_lock(&mutex) != 0) {
fprintf(stderr, "task_thread: couldn't lock mutex\n");
return (1);
}
task++;
if (mutex_unlock(&mutex) != 0) {
fprintf(stderr, "main thread: couldn't unlock mutex\n");
return (1);
}
if (use_broadcast)
cond_broadcast(&cv);
else
cond_signal(&cv);
thr_yield();
}
while (task != 0) {
thr_yield();
}
if (mutex_lock(&mutex) != 0) {
fprintf(stderr, "task_thread: couldn't lock mutex\n");
return (1);
}
task = -1;
if (mutex_unlock(&mutex) != 0) {
fprintf(stderr, "main thread: couldn't unlock mutex\n");
return (1);
}
cond_broadcast(&cv);
for (i=0; i<num_threads; i++) {
void *rv;
thr_join(tids[i], NULL, &rv);
printf("tread %d, processed %d events, rv = %d\n", tids[i],
processed[i], (int) rv);
}
return (0);
}
_______________________________________________
opensolaris-discuss mailing list
[email protected]