1ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/** pthread_spinloc_t test. */
2ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
3ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
4ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* Make sure pthread_spinlock_t is available when compiling with older glibc
5ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown * versions (2.3 or before).
6ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown */
7ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#define _GNU_SOURCE
8ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
9ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <pthread.h>
10ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <stdio.h>   /* fprintf() */
11ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <stdlib.h>  /* atoi() */
12ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
13ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
14ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic pthread_barrier_t  s_barrier;
15ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic pthread_spinlock_t s_spinlock;
16ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic int s_iterations;
17ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic int s_counter;
18ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
19ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
20ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void* thread_func(void* arg)
21ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
22ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  int i;
23ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
24ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  pthread_barrier_wait(&s_barrier);
25ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  for (i = s_iterations; i > 0; i--)
26ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  {
27ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    pthread_spin_lock(&s_spinlock);
28ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    s_counter++;
29ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    pthread_spin_unlock(&s_spinlock);
30ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  }
31ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return 0;
32ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
33ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
34ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownint main(int argc, char** argv)
35ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{
36ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  int i;
37ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  const int n_threads = 10;
38ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  pthread_t tid[n_threads];
39ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
40ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  s_iterations = argc > 1 ? atoi(argv[1]) : 1000;
41ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown
42ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  fprintf(stderr, "Start of test.\n");
43ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  pthread_barrier_init(&s_barrier, 0, n_threads);
44ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  pthread_spin_init(&s_spinlock, 0);
45ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  for (i = 0; i < n_threads; i++)
46ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    pthread_create(&tid[i], 0, thread_func, 0);
47ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  for (i = 0; i < n_threads; i++)
48ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    pthread_join(tid[i], 0);
49ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  pthread_spin_destroy(&s_spinlock);
50ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  pthread_barrier_destroy(&s_barrier);
51ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  if (s_counter == n_threads * s_iterations)
52ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    fprintf(stderr, "Test successful.\n");
53ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  else
54ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown    fprintf(stderr, "Test failed: counter = %d, should be %d\n",
55ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown            s_counter, n_threads * s_iterations);
56ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown  return 0;
57ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown}
58