OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [uClibc/] [test/] [pthread/] [ex3.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1325 phoenix
/* Multi-thread searching.
2
   Illustrates: thread cancellation, cleanup handlers. */
3
 
4
#include <errno.h>
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 */
15
void *search(void *);
16
void print_it(void *);
17
 
18
/* Global variables */
19
pthread_t threads[NUM_THREADS];
20
pthread_mutex_t lock;
21
int tries;
22
volatile int started;
23
 
24
int main(int argc, char ** argv)
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 */
34
  pthread_mutex_init(&lock, NULL);
35
 
36
  /* Create the searching threads */
37
  for (started=0; started<NUM_THREADS; started++)
38
    pthread_create(&threads[started], NULL, search, (void *)pid);
39
 
40
  /* Wait for (join) all the searching threads */
41
  for (i=0; i<NUM_THREADS; i++)
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
 
50
/* This is the cleanup function that is called
51
   when the threads are cancelled */
52
 
53
void 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 */
62
  printf("Thread %lx was canceled on its %d try.\n", tid, *try);
63
}
64
 
65
/* This is the search routine that is executed in each thread */
66
 
67
void *search(void *arg)
68
{
69
  int num = (int) arg;
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 */
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
 
85
  srand((int)tid);
86
  i = rand() & 0xFFFFFF;
87
  pthread_mutex_unlock(&lock);
88
  ntries = 0;
89
 
90
  /* Set the cancellation parameters --
91
     - Enable thread cancellation
92
     - Defer the action of the cancellation */
93
 
94
  pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
95
  pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);
96
 
97
  while (started < NUM_THREADS)
98
    sched_yield ();
99
 
100
  /* Push the cleanup routine (print_it) onto the thread
101
     cleanup stack.  This routine will be called when the
102
     thread is cancelled.  Also note that the pthread_cleanup_push
103
     call must have a matching pthread_cleanup_pop call.  The
104
     push and pop calls MUST be at the same lexical level
105
     within the code */
106
 
107
  /* Pass address of `ntries' since the current value of `ntries' is not
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 */
130
      for (j=0; j<NUM_THREADS; j++)
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
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.