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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gdb-6.8/] [gdb/] [testsuite/] [gdb.threads/] [linux-dp.c] - Blame information for rev 840

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 24 jeremybenn
/* linux-dp.c --- dining philosophers, on LinuxThreads
2
   Jim Blandy <jimb@cygnus.com> --- March 1999  */
3
 
4
/* It's okay to edit this file and shift line numbers around.  The
5
   tests use gdb_get_line_number to find source locations, so they
6
   don't depend on having certain line numbers in certain places.  */
7
 
8
#include <stdarg.h>
9
#include <stdlib.h>
10
#include <stdio.h>
11
#include <pthread.h>
12
#include <sys/time.h>
13
#include <sys/types.h>
14
 
15
/* The number of philosophers at the table.  */
16
int num_philosophers;
17
 
18
/* Mutex ordering -
19
   If you want to lock a mutex M, all the mutexes you have locked
20
   already must appear before M on this list.
21
 
22
   fork_mutex[0]
23
   fork_mutex[1]
24
   ...
25
   fork_mutex[num_philosophers - 1]
26
   stdout_mutex
27
   random_mutex
28
*/
29
 
30
/* You must hold this mutex while writing to stdout.  */
31
pthread_mutex_t stdout_mutex;
32
 
33
/* You must hold this mutex while calling any of the random number
34
   generation routines.  */
35
pthread_mutex_t random_mutex;
36
 
37
/* array of mutexes, one for each fork; fork_mutex[i] is to the left
38
   of philosopher i.  A philosopher is holding fork i iff his/her
39
   thread has locked fork_mutex[i].  */
40
pthread_mutex_t *fork_mutex;
41
 
42
/* array of threads, one representing each philosopher.  */
43
pthread_t *philosophers;
44
 
45
void *
46
xmalloc (size_t n)
47
{
48
  void *p = malloc (n);
49
 
50
  if (! p)
51
    {
52
      fprintf (stderr, "out of memory\n");
53
      exit (2);
54
    }
55
 
56
  return p;
57
}
58
 
59
void
60
shared_printf (char *format, ...)
61
{
62
  va_list ap;
63
 
64
  va_start (ap, format);
65
  pthread_mutex_lock (&stdout_mutex);
66
  vprintf (format, ap);
67
  pthread_mutex_unlock (&stdout_mutex);
68
  va_end (ap);
69
}
70
 
71
int
72
shared_random ()
73
{
74
  static unsigned int seed;
75
  int result;
76
 
77
  pthread_mutex_lock (&random_mutex);
78
  result = rand_r (&seed);
79
  pthread_mutex_unlock (&random_mutex);
80
  return result;
81
}
82
 
83
void
84
my_usleep (long usecs)
85
{
86
  struct timeval timeout;
87
 
88
  timeout.tv_sec = usecs / 1000000;
89
  timeout.tv_usec = usecs % 1000000;
90
 
91
  select (0, 0, 0, 0, &timeout);
92
}
93
 
94
void
95
random_delay ()
96
{
97
  my_usleep ((shared_random () % 2000) * 100);
98
}
99
 
100
void
101
print_philosopher (int n, char left, char right)
102
{
103
  int i;
104
 
105
  shared_printf ("%*s%c %d %c\n", (n * 4) + 2, "", left, n, right);
106
}
107
 
108
void *
109
philosopher (void *data)
110
{
111
  int n = * (int *) data;
112
 
113
  print_philosopher (n, '_', '_');
114
 
115
#if 1
116
  if (n == num_philosophers - 1)
117
    for (;;)
118
      {
119
        /* The last philosopher is different.  He goes for his right
120
           fork first, so there is no cycle in the mutex graph.  */
121
 
122
        /* Grab the right fork.  */
123
        pthread_mutex_lock (&fork_mutex[(n + 1) % num_philosophers]);
124
        print_philosopher (n, '_', '!');
125
        random_delay ();
126
 
127
        /* Then grab the left fork. */
128
        pthread_mutex_lock (&fork_mutex[n]);
129
        print_philosopher (n, '!', '!');
130
        random_delay ();
131
 
132
        print_philosopher (n, '_', '_');
133
        pthread_mutex_unlock (&fork_mutex[n]);
134
        pthread_mutex_unlock (&fork_mutex[(n + 1) % num_philosophers]);
135
        random_delay ();
136
      }
137
  else
138
#endif
139
    for (;;)
140
      {
141
        /* Grab the left fork. */
142
        pthread_mutex_lock (&fork_mutex[n]);
143
        print_philosopher (n, '!', '_');
144
        random_delay ();
145
 
146
        /* Then grab the right fork.  */
147
        pthread_mutex_lock (&fork_mutex[(n + 1) % num_philosophers]);
148
        print_philosopher (n, '!', '!');
149
        random_delay ();
150
 
151
        print_philosopher (n, '_', '_');
152
        pthread_mutex_unlock (&fork_mutex[n]);
153
        pthread_mutex_unlock (&fork_mutex[(n + 1) % num_philosophers]);
154
        random_delay ();
155
      }
156
 
157
  return (void *) 0;
158
}
159
 
160
int
161
main (int argc, char **argv)
162
{
163
  num_philosophers = 5;
164
 
165
  /* Set up the mutexes.  */
166
  {
167
    pthread_mutexattr_t ma;
168
    int i;
169
 
170
    pthread_mutexattr_init (&ma);
171
    pthread_mutex_init (&stdout_mutex, &ma);
172
    pthread_mutex_init (&random_mutex, &ma);
173
    fork_mutex = xmalloc (num_philosophers * sizeof (fork_mutex[0]));
174
    for (i = 0; i < num_philosophers; i++)
175
      pthread_mutex_init (&fork_mutex[i], &ma);
176
    pthread_mutexattr_destroy (&ma);
177
  }
178
 
179
  /* Set off the threads.  */
180
  {
181
    int i;
182
    int *numbers = xmalloc (num_philosophers * sizeof (*numbers));
183
    pthread_attr_t ta;
184
 
185
    philosophers = xmalloc (num_philosophers * sizeof (*philosophers));
186
 
187
    pthread_attr_init (&ta);
188
 
189
    for (i = 0; i < num_philosophers; i++)
190
      {
191
        numbers[i] = i;
192
        /* linuxthreads.exp: create philosopher */
193
        pthread_create (&philosophers[i], &ta, philosopher, &numbers[i]);
194
      }
195
 
196
    pthread_attr_destroy (&ta);
197
  }
198
 
199
  /* linuxthreads.exp: info threads 2 */
200
  sleep (1000000);
201
 
202
  /* Drink yourself into oblivion.  */
203
  for (;;)
204
    sleep (1000000);
205
 
206
  return 0;
207
}

powered by: WebSVN 2.1.0

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