1 /****************************************************************************** 2 * 3 * Copyright International Business Machines Corp., 2006, 2008 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 2 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 13 * the GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program; if not, write to the Free Software 17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 18 * 19 * NAME 20 * sbrk-mutex.c 21 * 22 * DESCRIPTION 23 * Create NUM_THREADS to walk through an array of malloc'd pthread mutexes. 24 * Each thread holds up to NUM_CONCURRENT locks at a time. 25 * 26 * USAGE: 27 * Use run_auto.sh script in current directory to build and run test. 28 * 29 * AUTHOR 30 * Darren Hart <dvhltc (at) us.ibm.com> 31 * 32 * HISTORY 33 * 2006-02-28: Initial version by Darren Hart 34 * 2006-03-01: Changed mutexes to PTHREAD_MUTEX_ROBUST_NP type -Sripathi Kodi 35 * 36 *****************************************************************************/ 37 38 #include <stdio.h> 39 #include <stdlib.h> 40 #include <signal.h> 41 #include <time.h> 42 #include <pthread.h> 43 #include <sched.h> 44 #include <errno.h> 45 #include <unistd.h> 46 #include "librttest.h" 47 48 #if HAS_PTHREAD_MUTEXTATTR_ROBUST_APIS 49 50 #define NUM_MUTEXES 5000 51 #define NUM_THREADS 50 52 #define NUM_CONCURRENT_LOCKS 50 53 #define DELAY 1000 /* how long to sleep in the worker thread in us */ 54 55 static pthread_mutex_t *mutexes[NUM_MUTEXES]; 56 57 void usage(void) 58 { 59 rt_help(); 60 printf("sbrk_mutex specific options:\n"); 61 } 62 63 int parse_args(int c, char *v) 64 { 65 66 int handled = 1; 67 switch (c) { 68 case 'h': 69 usage(); 70 exit(0); 71 default: 72 handled = 0; 73 break; 74 } 75 return handled; 76 } 77 78 void *worker_thread(void *arg) 79 { 80 int i; 81 82 for (i = 0; i < NUM_MUTEXES + NUM_CONCURRENT_LOCKS; i++) { 83 /* release prior lock */ 84 if (i >= NUM_CONCURRENT_LOCKS) { 85 pthread_mutex_unlock(mutexes[i - NUM_CONCURRENT_LOCKS]); 86 } 87 /* grab a new lock */ 88 if (i < NUM_MUTEXES) { 89 pthread_mutex_lock(mutexes[i]); 90 } 91 92 usleep(DELAY); 93 94 if (_dbg_lvl) 95 printf("thread %ld @ %d\n", (long)arg, i); 96 } 97 return NULL; 98 } 99 100 int main(int argc, char *argv[]) 101 { 102 int m, ret, robust; 103 intptr_t t; 104 pthread_mutexattr_t mutexattr; 105 setup(); 106 107 rt_init("h", parse_args, argc, argv); 108 109 if (pthread_mutexattr_init(&mutexattr) != 0) { 110 printf("Failed to init mutexattr\n"); 111 } 112 if (pthread_mutexattr_setrobust_np(&mutexattr, PTHREAD_MUTEX_ROBUST_NP) 113 != 0) { 114 printf("Can't set mutexattr robust\n"); 115 } 116 if (pthread_mutexattr_getrobust_np(&mutexattr, &robust) != 0) { 117 printf("Can't get mutexattr robust\n"); 118 } else { 119 printf("robust in mutexattr is %d\n", robust); 120 } 121 122 /* malloc and initialize the mutexes */ 123 printf("allocating and initializing %d mutexes\n", NUM_MUTEXES); 124 for (m = 0; m < NUM_MUTEXES; m++) { 125 if (!(mutexes[m] = malloc(sizeof(pthread_mutex_t)))) { 126 perror("malloc failed\n"); 127 } 128 if ((ret = pthread_mutex_init(mutexes[m], &mutexattr))) { 129 perror("pthread_mutex_init() failed\n"); 130 } 131 } 132 printf("mutexes allocated and initialized successfully\n"); 133 134 /* start children threads to walk the array, grabbing the locks */ 135 for (t = 0; t < NUM_THREADS; t++) { 136 create_fifo_thread(worker_thread, (void *)t, 137 sched_get_priority_min(SCHED_FIFO)); 138 } 139 /* wait for the children to complete */ 140 printf("joining threads\n"); 141 join_threads(); 142 /* destroy all the mutexes */ 143 for (m = 0; m < NUM_MUTEXES; m++) { 144 if (mutexes[m]) { 145 if ((ret = pthread_mutex_destroy(mutexes[m]))) 146 perror("pthread_mutex_destroy() failed\n"); 147 free(mutexes[m]); 148 } 149 } 150 151 return 0; 152 } 153 154 #else 155 int main(void) 156 { 157 printf 158 ("Your system doesn't support the pthread robust mutexattr APIs\n"); 159 return 1; 160 } 161 #endif 162