]> git.ipfire.org Git - thirdparty/glibc.git/blame - linuxthreads/Examples/ex3.c
Test for stack alignment.
[thirdparty/glibc.git] / linuxthreads / Examples / ex3.c
CommitLineData
5afdca00
UD
1/* Multi-thread searching.
2 Illustrates: thread cancellation, cleanup handlers. */
3
0302fece 4#include <errno.h>
5afdca00
UD
5#include <stdio.h>
6#include <unistd.h>
7#include <stdlib.h>
8#include <sys/types.h>
9#include <pthread.h>
10
11/* Defines the number of searching threads */
12#define NUM_THREADS 5
13
14/* Function prototypes */
15void *search(void *);
16void print_it(void *);
17
18/* Global variables */
19pthread_t threads[NUM_THREADS];
20pthread_mutex_t lock;
21int tries;
e3743e2f 22volatile int started;
5afdca00 23
0302fece 24int main(int argc, char ** argv)
5afdca00
UD
25{
26 int i;
27 int pid;
28
29 /* create a number to search for */
30 pid = getpid();
31 printf("Searching for the number = %d...\n", pid);
32
33 /* Initialize the mutex lock */
0302fece 34 pthread_mutex_init(&lock, NULL);
5afdca00
UD
35
36 /* Create the searching threads */
e3743e2f 37 for (started=0; started<NUM_THREADS; started++)
59553897 38 pthread_create(&threads[started], NULL, search, (void *) (long int) pid);
5afdca00
UD
39
40 /* Wait for (join) all the searching threads */
0302fece 41 for (i=0; i<NUM_THREADS; i++)
5afdca00
UD
42 pthread_join(threads[i], NULL);
43
44 printf("It took %d tries to find the number.\n", tries);
45
46 /* Exit the program */
47 return 0;
48}
49
0302fece 50/* This is the cleanup function that is called
5afdca00
UD
51 when the threads are cancelled */
52
53void print_it(void *arg)
54{
55 int *try = (int *) arg;
56 pthread_t tid;
57
58 /* Get the calling thread's ID */
59 tid = pthread_self();
60
61 /* Print where the thread was in its search when it was cancelled */
0302fece 62 printf("Thread %lx was canceled on its %d try.\n", tid, *try);
5afdca00
UD
63}
64
65/* This is the search routine that is executed in each thread */
66
67void *search(void *arg)
68{
59553897 69 int num = (long int) arg;
5afdca00
UD
70 int i, j, ntries;
71 pthread_t tid;
72
73 /* get the calling thread ID */
74 tid = pthread_self();
75
76 /* use the thread ID to set the seed for the random number generator */
77 /* Since srand and rand are not thread-safe, serialize with lock */
e3743e2f
UD
78
79 /* Try to lock the mutex lock --
80 if locked, check to see if the thread has been cancelled
81 if not locked then continue */
82 while (pthread_mutex_trylock(&lock) == EBUSY)
83 pthread_testcancel();
84
5afdca00
UD
85 srand((int)tid);
86 i = rand() & 0xFFFFFF;
87 pthread_mutex_unlock(&lock);
88 ntries = 0;
89
90 /* Set the cancellation parameters --
0302fece 91 - Enable thread cancellation
5afdca00
UD
92 - Defer the action of the cancellation */
93
94 pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
95 pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);
96
e3743e2f
UD
97 while (started < NUM_THREADS)
98 sched_yield ();
99
5afdca00 100 /* Push the cleanup routine (print_it) onto the thread
0302fece 101 cleanup stack. This routine will be called when the
5afdca00
UD
102 thread is cancelled. Also note that the pthread_cleanup_push
103 call must have a matching pthread_cleanup_pop call. The
0302fece 104 push and pop calls MUST be at the same lexical level
5afdca00
UD
105 within the code */
106
0302fece 107 /* Pass address of `ntries' since the current value of `ntries' is not
5afdca00
UD
108 the one we want to use in the cleanup function */
109
110 pthread_cleanup_push(print_it, (void *)&ntries);
111
112 /* Loop forever */
113 while (1) {
114 i = (i + 1) & 0xFFFFFF;
115 ntries++;
116
117 /* Does the random number match the target number? */
118 if (num == i) {
119 /* Try to lock the mutex lock --
120 if locked, check to see if the thread has been cancelled
121 if not locked then continue */
122 while (pthread_mutex_trylock(&lock) == EBUSY)
123 pthread_testcancel();
124
125 /* Set the global variable for the number of tries */
126 tries = ntries;
127 printf("Thread %lx found the number!\n", tid);
128
129 /* Cancel all the other threads */
0302fece 130 for (j=0; j<NUM_THREADS; j++)
5afdca00
UD
131 if (threads[j] != tid) pthread_cancel(threads[j]);
132
133 /* Break out of the while loop */
134 break;
135 }
136
137 /* Every 100 tries check to see if the thread has been cancelled. */
138 if (ntries % 100 == 0) {
139 pthread_testcancel();
140 }
141 }
142
143 /* The only way we can get here is when the thread breaks out
144 of the while loop. In this case the thread that makes it here
145 has found the number we are looking for and does not need to run
146 the thread cleanup function. This is why the pthread_cleanup_pop
147 function is called with a 0 argument; this will pop the cleanup
148 function off the stack without executing it */
149
150 pthread_cleanup_pop(0);
151 return((void *)0);
152}