1 /*
2 * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
3 * University Research and Technology
4 * Corporation. All rights reserved.
5 * Copyright (c) 2004-2005 The University of Tennessee and The University
6 * of Tennessee Research Foundation. All rights
7 * reserved.
8 * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
9 * University of Stuttgart. All rights reserved.
10 * Copyright (c) 2004-2005 The Regents of the University of California.
11 * All rights reserved.
12 * Copyright (c) 2010 Cisco Systems, Inc. All rights reserved.
13 * Copyright (c) 2015 Research Organization for Information Science
14 * and Technology (RIST). All rights reserved.
15 * $COPYRIGHT$
16 *
17 * Additional copyrights may follow
18 *
19 * $HEADER$
20 */
21
22 #define OMPI_BUILDING 0
23 #include "opal_config.h"
24
25 #ifdef HAVE_PTHREAD_H
26 #include <pthread.h>
27 #endif
28 #include <stdlib.h>
29 #include <stdio.h>
30
31 #include "opal/sys/atomic.h"
32
33 #define TEST_REPS 500
34
35 int atomic_verbose = 0;
36
37 struct start_info {
38 int tid;
39 int count;
40 opal_atomic_lock_t *lock;
41 };
42
43 static int atomic_spinlock_test(opal_atomic_lock_t *lock, int count, int id);
44
atomic_spinlock_start(void * arg)45 static void* atomic_spinlock_start(void* arg)
46 {
47 struct start_info *data = (struct start_info*) arg;
48
49 return (void*) (unsigned long) atomic_spinlock_test(data->lock, data->count,
50 data->tid);
51 }
52
53 static int
atomic_spinlock_test_th(opal_atomic_lock_t * lock,int count,int id,int thr_count)54 atomic_spinlock_test_th(opal_atomic_lock_t *lock, int count, int id, int thr_count)
55 {
56 pthread_t *th;
57 int tid, ret = 0;
58 struct start_info *data;
59
60 th = (pthread_t *) malloc(thr_count * sizeof(pthread_t));
61 if (!th) { perror("malloc"); exit(EXIT_FAILURE); }
62 data = (struct start_info *) malloc(thr_count * sizeof(struct start_info));
63 if (!th) { perror("malloc"); exit(EXIT_FAILURE); }
64
65 for (tid = 0; tid < thr_count; tid++) {
66 data[tid].tid = tid;
67 data[tid].count = count;
68 data[tid].lock = lock;
69
70 if (pthread_create(&th[tid], NULL, atomic_spinlock_start, (void *) &(data[tid])) != 0) {
71 perror("pthread_create");
72 exit(EXIT_FAILURE);
73 }
74 }
75
76 /* -- wait for the thread set to finish -- */
77 for (tid = 0; tid < thr_count; tid++) {
78 void *thread_return;
79
80 if (pthread_join(th[tid], &thread_return) != 0) {
81 perror("pthread_join");
82 exit(EXIT_FAILURE);
83 }
84
85 ret += (int) (unsigned long) thread_return;
86 }
87 free(data);
88 free(th);
89
90 return ret;
91 }
92
93
94 static int
atomic_spinlock_test(opal_atomic_lock_t * lock,int count,int id)95 atomic_spinlock_test(opal_atomic_lock_t *lock, int count, int id)
96 {
97 int i;
98
99 for (i = 0 ; i < count ; ++i) {
100 opal_atomic_lock(lock);
101 if (atomic_verbose) { printf("id %03d has the lock (lock)\n", id); }
102 opal_atomic_unlock(lock);
103
104 while (opal_atomic_trylock(lock)) { ; }
105 if (atomic_verbose) { printf("id %03d has the lock (trylock)\n", id); }
106 opal_atomic_unlock(lock);
107 }
108
109 return 0;
110 }
111
112
113 int
main(int argc,char * argv[])114 main(int argc, char *argv[])
115 {
116 int ret = 77;
117 opal_atomic_lock_t lock;
118 int num_threads = 1;
119
120 if (argc != 2) {
121 printf("*** Incorrect number of arguments. Skipping test\n");
122 return 77;
123 }
124 num_threads = atoi(argv[1]);
125
126 opal_atomic_lock_init(&lock, OPAL_ATOMIC_LOCK_UNLOCKED);
127 ret = atomic_spinlock_test_th(&lock, TEST_REPS, 0, num_threads);
128
129 return ret;
130 }
131