119c4260faa3852e39fac956b460f575c09550866bart/** pthread_spinloc_t test. */
219c4260faa3852e39fac956b460f575c09550866bart
319c4260faa3852e39fac956b460f575c09550866bart
419c4260faa3852e39fac956b460f575c09550866bart/* Make sure pthread_spinlock_t is available when compiling with older glibc
519c4260faa3852e39fac956b460f575c09550866bart * versions (2.3 or before).
619c4260faa3852e39fac956b460f575c09550866bart */
719c4260faa3852e39fac956b460f575c09550866bart#define _GNU_SOURCE
819c4260faa3852e39fac956b460f575c09550866bart
919c4260faa3852e39fac956b460f575c09550866bart#include <pthread.h>
1019c4260faa3852e39fac956b460f575c09550866bart#include <stdio.h>   /* fprintf() */
1119c4260faa3852e39fac956b460f575c09550866bart#include <stdlib.h>  /* atoi() */
1219c4260faa3852e39fac956b460f575c09550866bart
1319c4260faa3852e39fac956b460f575c09550866bart
1419c4260faa3852e39fac956b460f575c09550866bartstatic pthread_barrier_t  s_barrier;
1519c4260faa3852e39fac956b460f575c09550866bartstatic pthread_spinlock_t s_spinlock;
1619c4260faa3852e39fac956b460f575c09550866bartstatic int s_iterations;
1719c4260faa3852e39fac956b460f575c09550866bartstatic int s_counter;
1819c4260faa3852e39fac956b460f575c09550866bart
1919c4260faa3852e39fac956b460f575c09550866bart
2019c4260faa3852e39fac956b460f575c09550866bartstatic void* thread_func(void* arg)
2119c4260faa3852e39fac956b460f575c09550866bart{
2219c4260faa3852e39fac956b460f575c09550866bart  int i;
2319c4260faa3852e39fac956b460f575c09550866bart
2419c4260faa3852e39fac956b460f575c09550866bart  pthread_barrier_wait(&s_barrier);
2519c4260faa3852e39fac956b460f575c09550866bart  for (i = s_iterations; i > 0; i--)
2619c4260faa3852e39fac956b460f575c09550866bart  {
2719c4260faa3852e39fac956b460f575c09550866bart    pthread_spin_lock(&s_spinlock);
2819c4260faa3852e39fac956b460f575c09550866bart    s_counter++;
2919c4260faa3852e39fac956b460f575c09550866bart    pthread_spin_unlock(&s_spinlock);
3019c4260faa3852e39fac956b460f575c09550866bart  }
3119c4260faa3852e39fac956b460f575c09550866bart  return 0;
3219c4260faa3852e39fac956b460f575c09550866bart}
3319c4260faa3852e39fac956b460f575c09550866bart
3419c4260faa3852e39fac956b460f575c09550866bartint main(int argc, char** argv)
3519c4260faa3852e39fac956b460f575c09550866bart{
3619c4260faa3852e39fac956b460f575c09550866bart  int i;
3719c4260faa3852e39fac956b460f575c09550866bart  const int n_threads = 10;
3819c4260faa3852e39fac956b460f575c09550866bart  pthread_t tid[n_threads];
3919c4260faa3852e39fac956b460f575c09550866bart
4019c4260faa3852e39fac956b460f575c09550866bart  s_iterations = argc > 1 ? atoi(argv[1]) : 1000;
4119c4260faa3852e39fac956b460f575c09550866bart
4219c4260faa3852e39fac956b460f575c09550866bart  fprintf(stderr, "Start of test.\n");
4319c4260faa3852e39fac956b460f575c09550866bart  pthread_barrier_init(&s_barrier, 0, n_threads);
4419c4260faa3852e39fac956b460f575c09550866bart  pthread_spin_init(&s_spinlock, 0);
4519c4260faa3852e39fac956b460f575c09550866bart  for (i = 0; i < n_threads; i++)
4619c4260faa3852e39fac956b460f575c09550866bart    pthread_create(&tid[i], 0, thread_func, 0);
4719c4260faa3852e39fac956b460f575c09550866bart  for (i = 0; i < n_threads; i++)
4819c4260faa3852e39fac956b460f575c09550866bart    pthread_join(tid[i], 0);
4919c4260faa3852e39fac956b460f575c09550866bart  pthread_spin_destroy(&s_spinlock);
5019c4260faa3852e39fac956b460f575c09550866bart  pthread_barrier_destroy(&s_barrier);
5119c4260faa3852e39fac956b460f575c09550866bart  if (s_counter == n_threads * s_iterations)
5219c4260faa3852e39fac956b460f575c09550866bart    fprintf(stderr, "Test successful.\n");
5319c4260faa3852e39fac956b460f575c09550866bart  else
5419c4260faa3852e39fac956b460f575c09550866bart    fprintf(stderr, "Test failed: counter = %d, should be %d\n",
5519c4260faa3852e39fac956b460f575c09550866bart            s_counter, n_threads * s_iterations);
5619c4260faa3852e39fac956b460f575c09550866bart  return 0;
5719c4260faa3852e39fac956b460f575c09550866bart}
58