2 /* This really exists to check that Thrcheck behaves plausibly
3 with pthread_once calls. Which it appears to.
5 The original source of this program is as shown below, although it
6 has been modified somewhat. See
7 http://www.oreilly.com/pub/a/oreilly/ask_tim/2001/codepolicy.html
8 for OReilly's policy on using bits of their code examples.
12 /********************************************************
13 * An example source module to accompany...
15 * "Using POSIX Threads: Programming with Pthreads"
16 * by Brad Nichols, Dick Buttlar, Jackie Farrell
17 * O'Reilly & Associates, Inc.
19 ********************************************************
22 * An example of using the pthreads_once() call to execute an
23 * initialization procedure.
25 * A program spawns multiple threads and each one tries to
26 * execute the routine welcome() using the once call. Only
27 * the first thread into the once routine will actually
30 * The program's main thread synchronizes its exit with the
31 * exit of the threads using the pthread_join() operation.
38 #include <sys/types.h>
43 /* With more than 2 threads, the precise error reports vary between
44 platforms, in terms of the number of races detected. Make life
45 simple and just have 2 threads and so just 1 race. */
48 static pthread_once_t welcome_once_block
= PTHREAD_ONCE_INIT
;
50 static int unprotected1
= 0;
51 static int unprotected2
= 0;
53 /* This is a hack: delay threads except the first enough so as to
54 ensure threads[0] gets to the pthread_once call first. This is so
55 as to ensure that this test produces results which aren't
56 scheduling sensitive. (sigh) */
57 void maybe_stall ( int myid
)
59 assert(myid
>= 0 && myid
< NUM_THREADS
);
65 printf("welcome: Welcome\n");
66 unprotected1
++; /* this is harmless */
69 void* child ( void* argV
) {
71 maybe_stall( *(int*)argV
);
72 r
= pthread_once(&welcome_once_block
, welcome
); assert(!r
);
73 printf("child: Hi, I'm thread %d\n", *(int*)argV
);
74 unprotected2
++; /* whereas this is a race */
80 pthread_t threads
[NUM_THREADS
];
82 id_arg
= (int *)malloc(NUM_THREADS
*sizeof(int));
84 printf("main: Hello\n");
85 for (i
= 0; i
< NUM_THREADS
; i
++) {
87 r
= pthread_create(&threads
[i
], NULL
, child
, &id_arg
[i
]);
91 for (i
= 0; i
< NUM_THREADS
; i
++) {
92 pthread_join(threads
[i
], NULL
);
93 /* printf("main: joined to thread %d\n", i); */
95 printf("main: Goodbye\n");