1/*
2 * Copyright (c) 2006 Apple Inc.  All Rights Reserved.
3 *
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28
29
30/*
31 *	Order of Execution
32 *
33 *	benchmark_init
34 *
35 *	benchmark_optswitch
36 *
37 *		benchmark_initrun
38 *
39 *			benchmark_initworker
40 *				benchmark_initbatch
41 *					benchmark
42 *				benchmark_finibatch
43 *				benchmark_initbatch
44 *					benchmark
45 *				benchmark_finibatch, etc.
46 *			benchmark_finiworker
47 *
48 *		benchmark_result
49 *
50 *		benchmark_finirun
51 *
52 *	benchmark_fini
53 */
54
55
56
57#ifdef	__sun
58#pragma ident	"@(#)lmbench_lat_sig_prot.c	1.0	08/16/06 Apple Inc."
59#endif
60
61
62
63#include <unistd.h>
64#include <stdlib.h>
65#include <stdio.h>
66#include <setjmp.h>
67#include <string.h>
68#include <stdint.h>
69#include <fcntl.h>
70#include <signal.h>
71#include <sys/types.h>
72#include <sys/mman.h>
73#include <errno.h>
74
75
76#include "../libmicro.h"
77
78/*
79 *	Your state variables should live in the tsd_t struct below
80 */
81
82static int optp = 1;
83static int optw = 0;
84static int optn = -1;
85static char	*optf = "/Volumes/data/darbench/bin-i386/lmbench_lat_sig_prot";
86static int *mappedfile;
87jmp_buf jumper;
88
89u_int64_t	caught, n;
90double	adj;
91void	handler(int s) { }
92jmp_buf	prot_env;
93
94typedef struct {
95	char*	fname;
96	char*	where;
97} tsd_t;
98
99
100void
101prot(int s)
102{
103	_longjmp(jumper, s);
104
105}
106
107
108/*ARGSUSED*/
109int
110benchmark_initbatch(void *tsd)
111{
112	/*
113	 * initialize your state variables here second
114	 */
115	(void) fprintf(stderr, "benchmark_initbatch: entry\n");
116
117	return (0);
118}
119
120int
121benchmark_finirun()
122{
123	return (0);
124}
125
126int
127benchmark_init()
128{
129	/*
130	 *	the lm_optstr must be defined here or no options for you
131	 *
132	 * 	...and the framework will throw an error
133	 *
134	 */
135	(void) sprintf(lm_optstr, "p:w:n:f");
136	/*
137	 *	working hypothesis:
138	 *
139	 * 	tsd_t is the struct that we can pass around our
140	 *	state info in
141	 *
142	 *	lm_tsdsize will allocate the space we need for this
143	 *	structure throughout the rest of the framework
144	 */
145	lm_tsdsize = sizeof (tsd_t);
146
147	(void) sprintf(lm_usage,
148	    "       [-p <parallelism>]\n"
149	    "       [-w <warmup>]\n"
150	    "       [-n <repetitions>]\n"
151	    "       [-f <filename>]\n"
152	    "notes: measures lmbench lat_sig prot\n");
153	(void) fprintf(stderr, "benchmark_init: entry\n");
154	lm_defB = 1;
155	return (0);
156}
157
158int
159benchmark_fini()
160{
161	return (0);
162}
163
164int
165benchmark_finibatch(void *tsd)
166{
167	/*
168	 *	more proof of state passing
169	 */
170	return (0);
171}
172
173char *
174benchmark_result()
175{
176	static char		result = '\0';
177	(void) fprintf(stderr, "benchmark_result\n");
178	return (&result);
179}
180
181int
182benchmark_finiworker(void *tsd)
183{
184	return (0);
185}
186
187int
188benchmark_optswitch(int opt, char *optarg)
189{
190	(void) fprintf(stderr, "benchmark_optswitch: entry\n");
191
192	switch (opt) {
193	case 'w':
194		optw = sizetoint(optarg);
195		break;
196	case 'n':
197		optn = sizetoint(optarg);
198		break;
199	case 'p':
200		optp = sizetoint(optarg);
201		break;
202	case 'f':
203		(void) fprintf(stderr, "benchmark_optswitch: FILENAME entry = %s\n",optf);
204		//strcpy(optf, optarg);
205		(void) fprintf(stderr, "benchmark_optswitch: FILENAME exit\n");
206		break;
207	default:
208		return (-1);
209	}
210	(void) fprintf(stderr, "benchmark_optswitch: exit\n");
211	return (0);
212}
213
214int
215benchmark_initworker(void *tsd)
216{
217	/*
218	 *	initialize your state variables here first
219	 */
220	tsd_t* ts = (tsd_t*)tsd;
221	int fd;
222	struct	sigaction sa;
223	(void) fprintf(stderr, "benchmark_initworker: entry = %s\n",optf);
224
225    ts->fname = optf;
226    fd = open(ts->fname, 0);
227    (void) fprintf(stderr, "benchmark_initworker: open result is %i\n",fd);
228	(void) fprintf(stderr, "benchmark_initworker: errno result is %d - \"%s\"\n",errno, strerror(errno));
229
230    ts->where = mmap(0,4096, PROT_READ, MAP_SHARED, fd, 0);
231    (void) fprintf(stderr, "benchmark_initworker: mmap result is %i\n",ts->where);
232	*mappedfile = (int) ts->where;
233	(void) fprintf(stderr, "benchmark_initworker: mappedfile result is %i\n",*mappedfile);
234
235    if ((long)ts->where == -1) {
236    	perror("mmap");
237    	exit(1);
238    }
239
240    sa.sa_handler = prot;
241	sigemptyset(&sa.sa_mask);
242	sa.sa_flags = 0;
243	sigaction(SIGSEGV, &sa, 0);
244	sigaction(SIGBUS, &sa, 0);
245
246
247    caught = 0;
248    n = lm_optB;
249	return (0);
250}
251
252int
253benchmark_initrun()
254{
255	(void) fprintf(stderr, "benchmark_initrun: entry\n");
256
257	return (0);
258}
259
260int
261benchmark(void *tsd, result_t *res)
262{
263	/*
264	 *	initialize your state variables here last
265	 *
266	 * 	and realize that you are paying for your initialization here
267	 *	and it is really a bad idea
268	 */
269	int i;
270	//tsd_t* ts = (tsd_t*)tsd;
271	(void) fprintf(stderr, "benchmark: lm_optB = %i\n",lm_optB);
272	for (i = 0; i < lm_optB; i++) {
273		if (_setjmp(jumper) == 0) {
274
275			*mappedfile= 1;
276		}
277	}
278	res->re_count = i;
279
280	return (0);
281}
282