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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.0/] [gdb/] [testsuite/] [gdb.threads/] [linux-dp.c] - Rev 106

Go to most recent revision | Compare with Previous | Blame | View Log

/* linux-dp.c --- dining philosophers, on LinuxThreads
   Jim Blandy <jimb@cygnus.com> --- March 1999  */
 
/* It's okay to edit this file and shift line numbers around.  The
   tests use gdb_get_line_number to find source locations, so they
   don't depend on having certain line numbers in certain places.  */
 
#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <sys/time.h>
#include <sys/types.h>
 
/* The number of philosophers at the table.  */
int num_philosophers;
 
/* Mutex ordering -
   If you want to lock a mutex M, all the mutexes you have locked
   already must appear before M on this list.
 
   fork_mutex[0]
   fork_mutex[1]
   ...
   fork_mutex[num_philosophers - 1]
   stdout_mutex
   random_mutex
*/
 
/* You must hold this mutex while writing to stdout.  */
pthread_mutex_t stdout_mutex;
 
/* You must hold this mutex while calling any of the random number
   generation routines.  */
pthread_mutex_t random_mutex;
 
/* array of mutexes, one for each fork; fork_mutex[i] is to the left
   of philosopher i.  A philosopher is holding fork i iff his/her
   thread has locked fork_mutex[i].  */
pthread_mutex_t *fork_mutex;
 
/* array of threads, one representing each philosopher.  */
pthread_t *philosophers;
 
void *
xmalloc (size_t n)
{
  void *p = malloc (n);
 
  if (! p)
    {
      fprintf (stderr, "out of memory\n");
      exit (2);
    }
 
  return p;
}
 
void
shared_printf (char *format, ...)
{
  va_list ap;
 
  va_start (ap, format);
  pthread_mutex_lock (&stdout_mutex);
  vprintf (format, ap);
  pthread_mutex_unlock (&stdout_mutex);
  va_end (ap);
}
 
int 
shared_random ()
{
  static unsigned int seed;
  int result;
 
  pthread_mutex_lock (&random_mutex);
  result = rand_r (&seed);
  pthread_mutex_unlock (&random_mutex);
  return result;
}
 
void
my_usleep (long usecs)
{
  struct timeval timeout;
 
  timeout.tv_sec = usecs / 1000000;
  timeout.tv_usec = usecs % 1000000;
 
  select (0, 0, 0, 0, &timeout);
}
 
void
random_delay ()
{
  my_usleep ((shared_random () % 2000) * 100);
}
 
void
print_philosopher (int n, char left, char right)
{
  int i;
 
  shared_printf ("%*s%c %d %c\n", (n * 4) + 2, "", left, n, right);
}
 
void *
philosopher (void *data)
{
  int n = * (int *) data;
 
  print_philosopher (n, '_', '_');
 
#if 1
  if (n == num_philosophers - 1)
    for (;;)
      {
	/* The last philosopher is different.  He goes for his right
	   fork first, so there is no cycle in the mutex graph.  */
 
	/* Grab the right fork.  */
	pthread_mutex_lock (&fork_mutex[(n + 1) % num_philosophers]);
	print_philosopher (n, '_', '!');
	random_delay ();
 
	/* Then grab the left fork. */
	pthread_mutex_lock (&fork_mutex[n]);
	print_philosopher (n, '!', '!');
	random_delay ();
 
	print_philosopher (n, '_', '_');
	pthread_mutex_unlock (&fork_mutex[n]);
	pthread_mutex_unlock (&fork_mutex[(n + 1) % num_philosophers]);
	random_delay ();
      }
  else
#endif
    for (;;)
      {
	/* Grab the left fork. */
	pthread_mutex_lock (&fork_mutex[n]);
	print_philosopher (n, '!', '_');
	random_delay ();
 
	/* Then grab the right fork.  */
	pthread_mutex_lock (&fork_mutex[(n + 1) % num_philosophers]);
	print_philosopher (n, '!', '!');
	random_delay ();
 
	print_philosopher (n, '_', '_');
	pthread_mutex_unlock (&fork_mutex[n]);
	pthread_mutex_unlock (&fork_mutex[(n + 1) % num_philosophers]);
	random_delay ();
      }
}
 
int
main (int argc, char **argv)
{
  num_philosophers = 5;
 
  /* Set up the mutexes.  */
  {
    pthread_mutexattr_t ma;
    int i;
 
    pthread_mutexattr_init (&ma);
    pthread_mutex_init (&stdout_mutex, &ma);
    pthread_mutex_init (&random_mutex, &ma);
    fork_mutex = xmalloc (num_philosophers * sizeof (fork_mutex[0]));
    for (i = 0; i < num_philosophers; i++)
      pthread_mutex_init (&fork_mutex[i], &ma);
    pthread_mutexattr_destroy (&ma);
  }
 
  /* Set off the threads.  */
  {
    int i;
    int *numbers = xmalloc (num_philosophers * sizeof (*numbers));
    pthread_attr_t ta;
 
    philosophers = xmalloc (num_philosophers * sizeof (*philosophers));
 
    pthread_attr_init (&ta);
 
    for (i = 0; i < num_philosophers; i++)
      {
	numbers[i] = i;
	/* linuxthreads.exp: create philosopher */
	pthread_create (&philosophers[i], &ta, philosopher, &numbers[i]);
      }
 
    pthread_attr_destroy (&ta);
  }
 
  /* linuxthreads.exp: info threads 2 */
  sleep (1000000);
 
  /* Drink yourself into oblivion.  */
  for (;;)
    sleep (1000000);
 
  return 0;
}
 

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

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