/* * CDDL HEADER START * * The contents of this file are subject to the terms * of the Common Development and Distribution License * (the "License"). You may not use this file except * in compliance with the License. * * You can obtain a copy of the license at * src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing * permissions and limitations under the License. * * When distributing Covered Code, include this CDDL * HEADER in each file and include the License file at * usr/src/OPENSOLARIS.LICENSE. If applicable, * add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your * own identifying information: Portions Copyright [yyyy] * [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 2005 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* * mutex */ #include #include #include #include #include #include "libmicro.h" static int optt = 0; static int optp = 0; static int opth = 0; static int opto = 0; pthread_mutex_t *lock; typedef struct { int ts_once; pthread_mutex_t *ts_lock; } tsd_t; int benchmark_init() { lm_tsdsize = sizeof (tsd_t); (void) sprintf(lm_usage, " [-t] (create dummy thread so we are multithreaded)\n" " [-p] (use inter-process mutex (not support everywhere))\n" " [-h usecs] (specify mutex hold time (default 0)\n" "notes: measures uncontended pthread_mutex_[un,]lock\n"); (void) sprintf(lm_optstr, "tph:o:"); (void) sprintf(lm_header, "%8s", "holdtime"); return (0); } /*ARGSUSED*/ int benchmark_optswitch(int opt, char *optarg) { switch (opt) { case 'p': optp = 1; break; case 't': optt = 1; break; case 'h': opth = sizetoint(optarg); break; case 'o': opto = sizetoint(optarg); break; default: return (-1); } return (0); } void * dummy(void *arg) { (void) pause(); return (arg); } int benchmark_initrun() { pthread_mutexattr_t attr; int errors = 0; /*LINTED*/ lock = (pthread_mutex_t *)mmap(NULL, getpagesize(), PROT_READ | PROT_WRITE, optp?(MAP_ANON | MAP_SHARED):MAP_ANON|MAP_PRIVATE, -1, 0L) + opto; if (lock == MAP_FAILED) { errors++; } else { (void) pthread_mutexattr_init(&attr); if (optp) (void) pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED); if (pthread_mutex_init(lock, &attr) != 0) errors++; } return (errors); } int benchmark_initworker(void *tsd) { int errors = 0; tsd_t *ts = (tsd_t *)tsd; if (optt) { pthread_t tid; if (pthread_create(&tid, NULL, dummy, NULL) != 0) { errors++; } } ts->ts_lock = lock; return (errors); } void spinme(int usecs) { long long s = getusecs(); while (getusecs() - s < usecs) ; } int benchmark(void *tsd, result_t *res) { tsd_t *ts = (tsd_t *)tsd; int i; for (i = 0; i < lm_optB; i ++) { (void) pthread_mutex_lock(ts->ts_lock); if (opth) spinme(opth); (void) pthread_mutex_unlock(ts->ts_lock); } res->re_count = lm_optB; return (0); } char * benchmark_result() { static char result[256]; (void) sprintf(result, "%8d", opth); return (result); }