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#include <unistd.h> 32#include <stdlib.h> 33#include <stdio.h> 34#include <string.h> 35#include <pthread.h> 36#include <errno.h> 37 38#include "libmicro.h" 39 40typedef struct { 41 pthread_t *ts_threads; 42 pthread_attr_t *ts_attr; 43 pthread_mutex_t ts_lock; 44} tsd_t; 45 46static int opts = 0; 47 48int 49benchmark_init() 50{ 51 lm_defN = "pthread"; 52 53 lm_tsdsize = sizeof (tsd_t); 54 55 (void) sprintf(lm_usage, 56 " [-s stacksize] (specify stacksize)\n" 57 "notes: measures pthread_create\n"); 58 59 (void) sprintf(lm_optstr, "s:"); 60 61 return (0); 62} 63 64int 65benchmark_optswitch(int opt, char *optarg) 66{ 67 switch (opt) { 68 case 's': 69 opts = sizetoll(optarg); 70 break; 71 default: 72 return (-1); 73 } 74 75 return (0); 76} 77 78int 79benchmark_initworker(void *tsd) 80{ 81 tsd_t *ts = (tsd_t *)tsd; 82 int errors = 0; 83 84 ts->ts_threads = calloc(lm_optB, sizeof (pthread_t)); 85 (void) pthread_mutex_init(&ts->ts_lock, NULL); 86 87 if (opts) { 88 ts->ts_attr = malloc(sizeof (pthread_attr_t)); 89 (void) pthread_attr_init(ts->ts_attr); 90 if ((errors = pthread_attr_setstacksize(ts->ts_attr, opts)) 91 != 0) { 92 errno = errors; 93 perror("pthread_attr_setstacksize"); 94 } 95 } else 96 ts->ts_attr = NULL; 97 98 return (errors?1:0); 99} 100 101int 102benchmark_initbatch(void *tsd) 103{ 104 tsd_t *ts = (tsd_t *)tsd; 105 106 (void) pthread_mutex_lock(&ts->ts_lock); 107 108 return (0); 109} 110 111 112void * 113func(void *tsd) 114{ 115 tsd_t *ts = (tsd_t *)tsd; 116 117 (void) pthread_mutex_lock(&ts->ts_lock); 118 (void) pthread_mutex_unlock(&ts->ts_lock); 119 120 return (tsd); 121} 122 123int 124benchmark(void *tsd, result_t *res) 125{ 126 int i; 127 tsd_t *ts = (tsd_t *)tsd; 128 int error; 129 130 for (i = 0; i < lm_optB; i++) { 131 if ((error = pthread_create(ts->ts_threads + i, 132 ts->ts_attr, func, tsd)) != 0) { 133 errno = error; 134 perror("pthread_create"); 135 ts->ts_threads[i] = 0; 136 res->re_errors++; 137 return (0); 138 } 139 } 140 res->re_count = lm_optB; 141 142 return (0); 143} 144 145int 146benchmark_finibatch(void *tsd) 147{ 148 tsd_t *ts = (tsd_t *)tsd; 149 int i; 150 int errors = 0; 151 152 (void) pthread_mutex_unlock(&ts->ts_lock); 153 154 for (i = 0; i < lm_optB; i++) 155 if (ts->ts_threads[i] == 0 || 156 pthread_join(ts->ts_threads[i], NULL) < 0) { 157 errors++; 158 } 159 return (errors); 160} 161