1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms 5 * of the Common Development and Distribution License 6 * (the "License"). You may not use this file except 7 * in compliance with the License. 8 * 9 * You can obtain a copy of the license at 10 * src/OPENSOLARIS.LICENSE 11 * or http://www.opensolaris.org/os/licensing. 12 * See the License for the specific language governing 13 * permissions and limitations under the License. 14 * 15 * When distributing Covered Code, include this CDDL 16 * HEADER in each file and include the License file at 17 * usr/src/OPENSOLARIS.LICENSE. If applicable, 18 * add the following below this CDDL HEADER, with the 19 * fields enclosed by brackets "[]" replaced with your 20 * own identifying information: Portions Copyright [yyyy] 21 * [name of copyright owner] 22 * 23 * CDDL HEADER END 24 */ 25 26 /* 27 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 28 * Use is subject to license terms. 29 */ 30 31 /* 32 * mutex 33 */ 34 35 #include <unistd.h> 36 #include <stdio.h> 37 #include <stdlib.h> 38 #include <pthread.h> 39 #include <sys/mman.h> 40 41 #include "libmicro.h" 42 43 static int optt = 0; 44 static int optp = 0; 45 static int opth = 0; 46 static int opto = 0; 47 48 pthread_mutex_t *lock; 49 50 typedef struct { 51 int ts_once; 52 pthread_mutex_t *ts_lock; 53 } tsd_t; 54 55 int 56 benchmark_init() 57 { 58 lm_tsdsize = sizeof (tsd_t); 59 60 (void) sprintf(lm_usage, 61 " [-t] (create dummy thread so we are multithreaded)\n" 62 " [-p] (use inter-process mutex (not support everywhere))\n" 63 " [-h usecs] (specify mutex hold time (default 0)\n" 64 "notes: measures uncontended pthread_mutex_[un,]lock\n"); 65 66 (void) sprintf(lm_optstr, "tph:o:"); 67 68 (void) sprintf(lm_header, "%8s", "holdtime"); 69 70 return (0); 71 } 72 73 /*ARGSUSED*/ 74 int 75 benchmark_optswitch(int opt, char *optarg) 76 { 77 switch (opt) { 78 case 'p': 79 optp = 1; 80 break; 81 82 case 't': 83 optt = 1; 84 break; 85 86 case 'h': 87 opth = sizetoint(optarg); 88 break; 89 90 case 'o': 91 opto = sizetoint(optarg); 92 break; 93 94 default: 95 return (-1); 96 } 97 return (0); 98 } 99 100 void * 101 dummy(void *arg) 102 { 103 (void) pause(); 104 return (arg); 105 } 106 107 int 108 benchmark_initrun() 109 { 110 pthread_mutexattr_t attr; 111 int errors = 0; 112 113 /*LINTED*/ 114 lock = (pthread_mutex_t *)mmap(NULL, 115 getpagesize(), 116 PROT_READ | PROT_WRITE, 117 optp?(MAP_ANON | MAP_SHARED):MAP_ANON|MAP_PRIVATE, 118 -1, 0L) + opto; 119 120 if (lock == MAP_FAILED) { 121 errors++; 122 } else { 123 (void) pthread_mutexattr_init(&attr); 124 if (optp) 125 (void) pthread_mutexattr_setpshared(&attr, 126 PTHREAD_PROCESS_SHARED); 127 128 if (pthread_mutex_init(lock, &attr) != 0) 129 errors++; 130 } 131 132 return (errors); 133 } 134 135 int 136 benchmark_initworker(void *tsd) 137 { 138 int errors = 0; 139 tsd_t *ts = (tsd_t *)tsd; 140 141 142 if (optt) { 143 pthread_t tid; 144 145 146 147 if (pthread_create(&tid, NULL, dummy, NULL) != 0) { 148 errors++; 149 } 150 } 151 152 ts->ts_lock = lock; 153 154 return (errors); 155 } 156 157 void 158 spinme(int usecs) 159 { 160 long long s = getusecs(); 161 162 while (getusecs() - s < usecs) 163 ; 164 } 165 166 int 167 benchmark(void *tsd, result_t *res) 168 { 169 tsd_t *ts = (tsd_t *)tsd; 170 int i; 171 172 for (i = 0; i < lm_optB; i ++) { 173 174 (void) pthread_mutex_lock(ts->ts_lock); 175 if (opth) 176 spinme(opth); 177 (void) pthread_mutex_unlock(ts->ts_lock); 178 179 } 180 181 res->re_count = lm_optB; 182 183 return (0); 184 } 185 186 char * 187 benchmark_result() 188 { 189 static char result[256]; 190 191 (void) sprintf(result, "%8d", opth); 192 193 return (result); 194 } 195