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 #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 
     40 typedef struct {
     41 	pthread_t 		*ts_threads;
     42 	pthread_attr_t		*ts_attr;
     43 	pthread_mutex_t		ts_lock;
     44 } tsd_t;
     45 
     46 static int				opts = 0;
     47 
     48 int
     49 benchmark_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 
     64 int
     65 benchmark_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 
     78 int
     79 benchmark_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 
    101 int
    102 benchmark_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 
    112 void *
    113 func(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 
    123 int
    124 benchmark(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 
    145 int
    146 benchmark_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