1/********************************************************
2 * An example source module to accompany...
3 *
4 * "Using POSIX Threads: Programming with Pthreads"
5 *     by Brad nichols, Dick Buttlar, Jackie Farrell
6 *     O'Reilly & Associates, Inc.
7 *
8 ********************************************************
9 *
10 * cvsimple.c
11 *
12 * Demonstrates pthread condvars.
13 *
14 */
15#include <unistd.h>
16#include <stdio.h>
17#include <pthread.h>
18
19#define NUM_THREADS  3
20#define TCOUNT 10
21#define COUNT_THRES 12
22
23int     condvar_was_hit = 0;
24int     count = 0;
25int     thread_ids[3] = {0,1,2};
26pthread_mutex_t count_lock=PTHREAD_MUTEX_INITIALIZER;
27pthread_cond_t count_hit_threshold=PTHREAD_COND_INITIALIZER;
28
29void *inc_count(void *null)
30{
31  int i=0;
32
33  for (i=0; i<TCOUNT; i++) {
34    pthread_mutex_lock(&count_lock);
35    count++;
36    printf("inc_counter(): count = %d, unlocking mutex\n", count);
37    if (count == COUNT_THRES) {
38      printf("hit threshold!\n");
39      pthread_cond_signal(&count_hit_threshold);
40    }
41    pthread_mutex_unlock(&count_lock);
42  }
43
44  return(NULL);
45}
46
47void *watch_count(void *null)
48{
49  pthread_mutex_lock(&count_lock);
50
51  while (count < COUNT_THRES) {
52    pthread_cond_wait(&count_hit_threshold, &count_lock);
53    condvar_was_hit = 1;
54  }
55
56  pthread_mutex_unlock(&count_lock);
57
58  return(NULL);
59}
60
61extern int
62main(void)
63{
64  int       i;
65  pthread_t threads[3];
66
67  pthread_create(&threads[0], NULL, watch_count, NULL);
68  sleep(1);
69  pthread_create(&threads[1], NULL, inc_count,   NULL);
70  pthread_create(&threads[2], NULL, inc_count,   NULL);
71
72  for (i = 0; i < NUM_THREADS; i++) {
73    pthread_join(threads[i], NULL);
74  }
75
76  // Nb: it's not certain that we'll hit here.  It's possible that the two
77  // inc_count threads could fully run before watch_count begins, and so
78  // pthread_cond_wait() is never called.  Or, we could get a spurious
79  // wake-up in watch_count().  Nonetheless, it's very likely that things
80  // will work out as expected, since we're starting watch_count() first.
81  // (Also since the sleep() call was added after watch_count()!)
82  if (condvar_was_hit == 1)
83    printf("condvar was hit!\n");
84  else if (condvar_was_hit > 1)
85    printf("condvar was multi-hit...\n");
86  else
87    printf("condvar was missed...\n");
88
89  return 0;
90}
91
92
93