~bkerensa/ubuntu/raring/valgrind/merge-from-deb

« back to all changes in this revision

Viewing changes to exp-drd/tests/pth_broadcast.c

  • Committer: Bazaar Package Importer
  • Author(s): Andrés Roldán
  • Date: 2008-06-13 02:31:40 UTC
  • mto: (1.4.1 upstream) (2.2.1 squeeze)
  • mto: This revision was merged to the branch mainline in revision 24.
  • Revision ID: james.westby@ubuntu.com-20080613023140-iwk33rz9rhvfkr96
Import upstream version 3.3.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Broadcast a (POSIX threads) signal to all running threads, where the 
 
2
// number of threads can be specified on the command line. This test program
 
3
// is intended not only to test the correctness of drd but also to test
 
4
// whether performance does not degrade too much when the number of threads
 
5
// increases.
 
6
 
 
7
 
 
8
#include <assert.h>
 
9
#include <pthread.h>
 
10
#include <stdio.h>
 
11
#include <stdlib.h>
 
12
#include <string.h>
 
13
#include <unistd.h>
 
14
 
 
15
 
 
16
// Counting semaphore.
 
17
 
 
18
struct csema
 
19
{
 
20
  pthread_mutex_t  m_mutex;
 
21
  pthread_cond_t   m_cond;
 
22
  int              m_count;
 
23
};
 
24
 
 
25
void csema_ctr(struct csema* p)
 
26
{
 
27
  memset(p, 0, sizeof(*p));
 
28
  pthread_mutex_init(&p->m_mutex, 0);
 
29
  pthread_cond_init(&p->m_cond, 0);
 
30
}
 
31
 
 
32
void csema_dtr(struct csema* p)
 
33
{
 
34
  pthread_cond_destroy(&p->m_cond);
 
35
  pthread_mutex_destroy(&p->m_mutex);
 
36
}
 
37
 
 
38
void csema_p(struct csema* p, const int n)
 
39
{
 
40
  pthread_mutex_lock(&p->m_mutex);
 
41
  while (p->m_count < n)
 
42
    pthread_cond_wait(&p->m_cond, &p->m_mutex);
 
43
  p->m_count -= n;
 
44
  pthread_cond_signal(&p->m_cond);
 
45
  pthread_mutex_unlock(&p->m_mutex);
 
46
}
 
47
 
 
48
void csema_v(struct csema* p)
 
49
{
 
50
  pthread_mutex_lock(&p->m_mutex);
 
51
  p->m_count++;
 
52
  pthread_cond_signal(&p->m_cond);
 
53
  pthread_mutex_unlock(&p->m_mutex);
 
54
}
 
55
 
 
56
 
 
57
struct cthread
 
58
{
 
59
  pthread_t     m_thread;
 
60
  int           m_threadnum;
 
61
  struct csema* m_sema;
 
62
};
 
63
 
 
64
void cthread_ctr(struct cthread* p)
 
65
{
 
66
  p->m_thread = 0;
 
67
  p->m_sema   = 0;
 
68
}
 
69
 
 
70
void cthread_dtr(struct cthread* p)
 
71
{ }
 
72
 
 
73
 
 
74
// Local variables.
 
75
 
 
76
static int s_debug = 0;
 
77
static int s_trace = 0;
 
78
static int s_signal_count;
 
79
static pthread_mutex_t s_mutex;
 
80
static pthread_cond_t  s_cond;
 
81
 
 
82
 
 
83
// Function definitions.
 
84
 
 
85
static void thread_func(struct cthread* thread_info)
 
86
{
 
87
  int i;
 
88
 
 
89
  pthread_mutex_lock(&s_mutex);
 
90
 
 
91
  for (i = 0; i < s_signal_count; i++)
 
92
  {
 
93
    if (s_trace)
 
94
    {
 
95
      printf("thread %d [%d] (1)\n", thread_info->m_threadnum, i);
 
96
    }
 
97
    csema_v(thread_info->m_sema);
 
98
    
 
99
    // Wait until the main thread signals us via pthread_cond_broadcast().
 
100
    pthread_cond_wait(&s_cond, &s_mutex);
 
101
    if (s_trace)
 
102
    {
 
103
      printf("thread %d [%d] (2)\n", thread_info->m_threadnum, i);
 
104
    }
 
105
  }
 
106
 
 
107
  pthread_mutex_unlock(&s_mutex);
 
108
}
 
109
 
 
110
int main(int argc, char** argv)
 
111
{
 
112
  int optchar;
 
113
  int thread_count;
 
114
 
 
115
  while ((optchar = getopt(argc, argv, "d")) != EOF)
 
116
  {
 
117
    switch (optchar)
 
118
    {
 
119
    case 'd':
 
120
      s_debug = 1;
 
121
      break;
 
122
    default:
 
123
      assert(0);
 
124
      break;
 
125
    }
 
126
  }
 
127
  s_signal_count = argc > optind ? atoi(argv[optind]) : 10;
 
128
  thread_count = argc > optind + 1 ? atoi(argv[optind + 1]) : 10;
 
129
 
 
130
  if (s_debug)
 
131
    printf("&s_cond = %p\n", &s_cond);
 
132
 
 
133
  pthread_mutex_init(&s_mutex, 0);
 
134
  pthread_cond_init(&s_cond, 0);
 
135
  {
 
136
    int i;
 
137
    struct csema sema;
 
138
    struct cthread* p;
 
139
    struct cthread* thread_vec;
 
140
 
 
141
    csema_ctr(&sema);
 
142
    thread_vec = malloc(sizeof(struct cthread) * thread_count);
 
143
    for (p = thread_vec; p != thread_vec + thread_count; p++)
 
144
    {
 
145
      cthread_ctr(p);
 
146
      p->m_threadnum = p - thread_vec;
 
147
      p->m_sema = &sema;
 
148
      pthread_create(&p->m_thread, 0,
 
149
                     (void*(*)(void*))thread_func, &*p);
 
150
    }
 
151
    for (i = 0; i < s_signal_count; i++)
 
152
    {
 
153
      if (s_trace)
 
154
        printf("main [%d] (1)\n", i);
 
155
      csema_p(&sema, thread_count);
 
156
      if (s_trace)
 
157
        printf("main [%d] (2)\n", i);
 
158
      pthread_mutex_lock(&s_mutex);
 
159
      pthread_cond_broadcast(&s_cond);
 
160
      pthread_mutex_unlock(&s_mutex);
 
161
      if (s_trace)
 
162
        printf("main [%d] (3)\n", i);
 
163
    }
 
164
    for (i = 0; i < thread_count; i++)
 
165
    {
 
166
      pthread_join(thread_vec[i].m_thread, 0);
 
167
      cthread_dtr(&thread_vec[i]);
 
168
    }
 
169
    free(thread_vec);
 
170
    csema_dtr(&sema);
 
171
  }
 
172
  pthread_cond_destroy(&s_cond);
 
173
  pthread_mutex_destroy(&s_mutex);
 
174
  return 0;
 
175
}