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 <sys/uio.h>
32#include <limits.h>
33#include <unistd.h>
34#include <stdlib.h>
35#include <stdio.h>
36#include <fcntl.h>
37
38#ifndef IOV_MAX
39#define	IOV_MAX			UIO_MAXIOV
40#endif
41
42#include "libmicro.h"
43
44typedef struct {
45	int			ts_once;
46	struct iovec		*ts_iov;
47	int 			ts_fd;
48} tsd_t;
49
50#define	DEFF			"/dev/null"
51#define	DEFS			1024
52#define	DEFV			10
53
54static char			*optf = DEFF;
55static int			opts = DEFS;
56static int			optv = DEFV;
57
58int
59benchmark_init()
60{
61	lm_tsdsize = sizeof (tsd_t);
62
63	(void) sprintf(lm_optstr, "f:s:v:");
64
65	(void) sprintf(lm_usage,
66	    "       [-f file-to-write (default %s)]\n"
67	    "       [-s buffer-size (default %d)]\n"
68	    "       [-v vector-size (default %d)]\n"
69	    "notes: measures writev()\n"
70	    "       IOV_MAX is %d\n"
71	    "       SSIZE_MAX is %ld\n",
72	    DEFF, DEFS, DEFV, IOV_MAX, SSIZE_MAX);
73
74	(void) sprintf(lm_header, "%8s %4s", "size", "vec");
75
76	lm_defB = 1;
77
78	return (0);
79}
80
81int
82benchmark_optswitch(int opt, char *optarg)
83{
84	switch (opt) {
85	case 'f':
86		optf = optarg;
87		break;
88	case 's':
89		opts = sizetoint(optarg);
90		break;
91	case 'v':
92		optv = atoi(optarg);
93		break;
94	default:
95		return (-1);
96	}
97	return (0);
98}
99
100int
101benchmark_initbatch(void *tsd)
102{
103	tsd_t			*ts = (tsd_t *)tsd;
104	int			i;
105	int			errors = 0;
106
107	if (ts->ts_once++ == 0) {
108		ts->ts_fd = open(optf, O_WRONLY);
109		if (ts->ts_fd == -1) {
110			errors++;
111		}
112		ts->ts_iov = (struct iovec *)malloc(
113		    optv * sizeof (struct iovec));
114		for (i = 0; i < optv; i++) {
115			ts->ts_iov[i].iov_base = malloc(opts);
116			ts->ts_iov[i].iov_len = opts;
117		}
118	}
119
120	(void) lseek(ts->ts_fd, 0, SEEK_SET);
121
122	return (errors);
123}
124
125int
126benchmark(void *tsd, result_t *res)
127{
128	tsd_t			*ts = (tsd_t *)tsd;
129	int			i;
130
131	for (i = 0; i < lm_optB; i++) {
132		if (writev(ts->ts_fd, ts->ts_iov, optv) != opts * optv) {
133			res->re_errors++;
134		}
135	}
136	res->re_count = i;
137
138	return (0);
139}
140
141char *
142benchmark_result()
143{
144	static char		result[256];
145
146	(void) sprintf(result, "%8d %4d", opts, optv);
147
148	return (result);
149}
150