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 * memcpy
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#define	DEFR			1
44
45static long long		opts = DEFS;
46static int			optf;
47static int			optt;
48static int			opta;
49
50typedef struct {
51	char			*ts_src;
52	char 			*ts_dest;
53	int			ts_srcsize;
54	int			ts_destsize;
55} tsd_t;
56
57int
58benchmark_init()
59{
60	lm_tsdsize = sizeof (tsd_t);
61
62	(void) sprintf(lm_optstr, "a:s:ft");
63
64	(void) sprintf(lm_usage,
65	    "       [-s buffer-size (default %d)]\n"
66	    "       [-a relative alignment (default page aligned)]\n"
67	    "       [-f (rotate \"from\" buffer to keep it out of cache)]\n"
68	    "       [-t (rotate \"to\" buffer to keep it out of cache)]\n"
69	    "notes: measures memcpy()\n",
70	    DEFS);
71
72	(void) sprintf(lm_header, "%8s", "size");
73
74	return (0);
75}
76
77int
78benchmark_optswitch(int opt, char *optarg)
79{
80	switch (opt) {
81	case 'f':
82		optf++;
83		break;
84	case 't':
85		optt++;
86		break;
87	case 's':
88		opts = sizetoll(optarg);
89		break;
90	case 'a':
91		opta = sizetoint(optarg);
92		break;
93	default:
94		return (-1);
95	}
96	return (0);
97}
98
99int
100benchmark_initworker(void *tsd)
101{
102	tsd_t			*ts = (tsd_t *)tsd;
103
104	if (optf)
105		ts->ts_srcsize = 64 * 1024 * 1024;
106	else
107		ts->ts_srcsize = opts + opta;
108
109	if (optt)
110		ts->ts_destsize = 64 * 1024 * 1024;
111	else
112		ts->ts_destsize = (int)opts;
113
114
115	ts->ts_src = opta + (char *)valloc(ts->ts_srcsize);
116	ts->ts_dest = valloc(ts->ts_destsize);
117
118	return (0);
119}
120
121int
122benchmark(void *tsd, result_t *res)
123{
124	tsd_t			*ts = (tsd_t *)tsd;
125	int			i;
126	char			*src = ts->ts_src;
127	char			*dest = ts->ts_dest;
128
129	int bump = (int)opts;
130
131	if (bump < 1024)
132		bump = 1024; /* avoid prefetched area */
133	for (i = 0; i < lm_optB; i++) {
134		(void) memcpy(dest, src, opts);
135		if (optf) {
136			src += bump;
137			if (src + opts > ts->ts_src + ts->ts_srcsize)
138				src = ts->ts_src;
139		}
140		if (optt) {
141			dest += bump;
142			if (dest + opts > ts->ts_dest + ts->ts_destsize)
143				dest = ts->ts_dest;
144		}
145	}
146
147	res->re_count = i;
148
149	return (0);
150}
151
152char *
153benchmark_result()
154{
155	static char		result[256];
156
157	(void) sprintf(result, "%8lld", opts);
158
159	return (result);
160}
161