Home | History | Annotate | Download | only in libmicro
      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