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 * memset
33 */
34
35#include <unistd.h>
36#include <stdlib.h>
37#include <stdio.h>
38#include <string.h>
39
40#include "libmicro.h"
41
42#define	DEFS			8192
43
44static long long		opts = DEFS;
45static int			opta = 0;
46static int			optu = 0;
47
48static char 			*optas = "4k";
49
50typedef struct {
51	char 			*ts_buff;
52	int			ts_size;
53	int			ts_offset;
54} tsd_t;
55
56int
57benchmark_init()
58{
59	lm_tsdsize = sizeof (tsd_t);
60
61	(void) sprintf(lm_optstr, "a:us:");
62
63	(void) sprintf(lm_usage,
64	    "       [-s buffer-size (default %d)]\n"
65	    "       [-a alignment (force buffer alignment)]\n"
66	    "       [-u (try to always use uncached memory)]"
67	    "notes: measures memset()\n",
68	    DEFS);
69
70	(void) sprintf(lm_header, "%8s%16s", "size", "alignment");
71
72	return (0);
73}
74
75int
76benchmark_optswitch(int opt, char *optarg)
77{
78	switch (opt) {
79	case 'u':
80		optu = 1;
81		break;
82	case 's':
83		opts = sizetoll(optarg);
84		break;
85	case 'a':
86		opta = sizetoll(optarg);
87		if (opta > 4096)
88			opta = 0;
89		else
90			optas = optarg;
91		break;
92	default:
93		return (-1);
94	}
95	return (0);
96}
97
98int
99benchmark_initworker(void *tsd)
100{
101	tsd_t 			*ts = (tsd_t *)tsd;
102	int			errors = 0;
103	int i;
104
105	if (optu) {
106		ts->ts_size 	= 1024 * 1024 * 64;
107		ts->ts_offset 	= opta;
108	} else {
109		ts->ts_size 	= opta + opts;
110		ts->ts_offset 	= opta;
111	}
112
113	if ((ts->ts_buff = (char *)valloc(ts->ts_size)) == NULL)
114		errors++;
115
116	for (i = 0; i < ts->ts_size; i++)
117		ts->ts_buff[i] = 0;
118	return (errors);
119}
120
121/*ARGSUSED*/
122int
123benchmark(void *tsd, result_t *res)
124{
125	int			i;
126	tsd_t			*ts = (tsd_t *)tsd;
127
128
129	if (optu) {
130		char *buf = ts->ts_buff + ts->ts_offset;
131		char *end = ts->ts_buff + ts->ts_size;
132		int offset = ts->ts_offset;
133
134		unsigned long tmp;
135
136		for (i = 0; i < lm_optB; i ++) {
137			(void) memset(buf, 0, opts);
138			tmp = (((unsigned long)buf + opts + 4095) & ~4095) + offset;
139			buf = (char *) tmp;
140			if (buf + opts > end)
141				buf = ts->ts_buff + offset;
142		}
143	} else {
144		char *buf = ts->ts_buff + ts->ts_offset;
145
146		for (i = 0; i < lm_optB; i += 10) {
147			(void) memset(buf, 0, opts);
148			(void) memset(buf, 0, opts);
149			(void) memset(buf, 0, opts);
150			(void) memset(buf, 0, opts);
151			(void) memset(buf, 0, opts);
152			(void) memset(buf, 0, opts);
153			(void) memset(buf, 0, opts);
154			(void) memset(buf, 0, opts);
155			(void) memset(buf, 0, opts);
156			(void) memset(buf, 0, opts);
157		}
158	}
159	res->re_count = i;
160
161	return (0);
162}
163
164char *
165benchmark_result()
166{
167	static char		result[256];
168
169	(void) sprintf(result, "%8lld%12s", opts, optas);
170
171	return (result);
172}
173