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 43static int optt = 0; 44static int optp = 0; 45static int opth = 0; 46static int opto = 0; 47 48pthread_mutex_t *lock; 49 50typedef struct { 51 int ts_once; 52 pthread_mutex_t *ts_lock; 53} tsd_t; 54 55int 56benchmark_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*/ 74int 75benchmark_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 100void * 101dummy(void *arg) 102{ 103 (void) pause(); 104 return (arg); 105} 106 107int 108benchmark_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 135int 136benchmark_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 157void 158spinme(int usecs) 159{ 160 long long s = getusecs(); 161 162 while (getusecs() - s < usecs) 163 ; 164} 165 166int 167benchmark(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 186char * 187benchmark_result() 188{ 189 static char result[256]; 190 191 (void) sprintf(result, "%8d", opth); 192 193 return (result); 194} 195