1da2e3ebdSchinref	-D_def_map_ast=1
2da2e3ebdSchin
3da2e3ebdSchinsys	mman
4da2e3ebdSchin
5da2e3ebdSchintst	lib_mmap note{ standard mmap interface that works }end execute{
6da2e3ebdSchin	#include <unistd.h>
7da2e3ebdSchin	#include <fcntl.h>
8da2e3ebdSchin	#include <sys/types.h>
9da2e3ebdSchin	#include <sys/mman.h>
10da2e3ebdSchin	#include <sys/stat.h>
11da2e3ebdSchin	#include <sys/times.h>
12da2e3ebdSchin
13da2e3ebdSchin	#define MAPSIZE (64*1024)
14da2e3ebdSchin	#define BUFSIZE	(8*1024)
15da2e3ebdSchin	#define WRITE   (64)
16da2e3ebdSchin
17da2e3ebdSchin	#define Failed(file)	(remove(file),1)
18da2e3ebdSchin
19da2e3ebdSchin	int
20da2e3ebdSchin	#if _STD_
21da2e3ebdSchin	main(int argc, char** argv)
22da2e3ebdSchin	#else
23da2e3ebdSchin	main(argc,argv)
24da2e3ebdSchin	int     argc;
25da2e3ebdSchin	char**  argv;
26da2e3ebdSchin	#endif
27da2e3ebdSchin	{
28da2e3ebdSchin		caddr_t		mm;
29da2e3ebdSchin		char		*t, *u, *f;
30da2e3ebdSchin		int		i, fd, okfixed;
31da2e3ebdSchin		char		file[1024], buf[MAPSIZE];
32da2e3ebdSchin		struct tms	stm, etm;
33da2e3ebdSchin		clock_t		rdtm, mmtm;
34da2e3ebdSchin
35da2e3ebdSchin		/* create data file in a local fs if possible */
36da2e3ebdSchin		t = file;
37da2e3ebdSchin		if (access(f = "/tmp", 0) == 0 ||
38da2e3ebdSchin		    access(f = "/usr/tmp", 0) == 0)
39da2e3ebdSchin		{
40da2e3ebdSchin			while (*t = *f++)
41da2e3ebdSchin				t++;
42da2e3ebdSchin			*t++ = '/';
43da2e3ebdSchin		}
44da2e3ebdSchin		u = t;
45da2e3ebdSchin		f = argv[0];
46da2e3ebdSchin		while (*t = *f++)
47da2e3ebdSchin			if (*t == '/')
48da2e3ebdSchin				t = u;
49da2e3ebdSchin			else if (*t != '.')
50da2e3ebdSchin				t++;
51da2e3ebdSchin		*t++ = '.'; *t++ = 'D'; *t = 0;
52da2e3ebdSchin		if ((fd = open(file, O_CREAT|O_TRUNC|O_WRONLY, 0666)) < 0)
53da2e3ebdSchin			return 1;
54da2e3ebdSchin
55da2e3ebdSchin		for (i = 0; i < sizeof(buf); ++i)
56da2e3ebdSchin			buf[i] = '0' + (i%10);
57da2e3ebdSchin		for (i = 0; i < WRITE; ++i)
58da2e3ebdSchin			if (write(fd,buf,sizeof(buf)) != sizeof(buf))
59da2e3ebdSchin				return Failed(file);
60da2e3ebdSchin		close(fd);
61da2e3ebdSchin
62da2e3ebdSchin		/* see if can overwrite fixed map */
63da2e3ebdSchin	#ifndef MAP_VARIABLE
64da2e3ebdSchin	#define MAP_VARIABLE	0
65da2e3ebdSchin	#endif
66da2e3ebdSchin		if ((fd = open(file, O_RDWR)) < 0)
67da2e3ebdSchin			return Failed(file);
68da2e3ebdSchin
69da2e3ebdSchin		mm = mmap((caddr_t)0, sizeof(buf), (PROT_READ|PROT_WRITE),
70da2e3ebdSchin			  (MAP_PRIVATE|MAP_VARIABLE), fd, 0);
71da2e3ebdSchin		if(mm == (caddr_t)0 || mm == (caddr_t)(-1))
72da2e3ebdSchin			return Failed(file);
73da2e3ebdSchin		mm = mmap(mm, sizeof(buf), (PROT_READ|PROT_WRITE),
74da2e3ebdSchin			  (MAP_PRIVATE|MAP_FIXED), fd, 0);
75da2e3ebdSchin		okfixed = (mm == (caddr_t)0 || mm == (caddr_t)(-1)) ? 0 : 1;
76da2e3ebdSchin		munmap(mm, sizeof(buf));
77da2e3ebdSchin		close(fd);
78da2e3ebdSchin
79da2e3ebdSchin		/* read time */
80da2e3ebdSchin		if((fd = open(file,  O_RDWR)) < 0)
81da2e3ebdSchin			return Failed(file);
82da2e3ebdSchin		times(&stm);
83da2e3ebdSchin		for (i = 0; i < WRITE; ++i)
84da2e3ebdSchin			if (read(fd,buf,BUFSIZE) != BUFSIZE)
85da2e3ebdSchin				return Failed(file);
86da2e3ebdSchin		times(&etm);
87da2e3ebdSchin		close(fd);
88da2e3ebdSchin		rdtm = (etm.tms_utime-stm.tms_utime) + (etm.tms_stime-stm.tms_stime);
89da2e3ebdSchin
90da2e3ebdSchin		/* mmap time */
91da2e3ebdSchin		if ((fd = open(file, O_RDWR)) < 0)
92da2e3ebdSchin			return Failed(file);
93da2e3ebdSchin		times(&stm);
94da2e3ebdSchin		for(i = 0, mm = (caddr_t)0; i < WRITE; ++i)
95da2e3ebdSchin		{	if(okfixed)
96da2e3ebdSchin			{	mm = (caddr_t)mmap(mm, MAPSIZE,
97da2e3ebdSchin					(PROT_READ|PROT_WRITE),
98da2e3ebdSchin					(MAP_PRIVATE | (mm ? MAP_FIXED : MAP_VARIABLE)),
99da2e3ebdSchin					fd, i*MAPSIZE );
100da2e3ebdSchin			}
101da2e3ebdSchin			else
102da2e3ebdSchin			{	if(mm)
103da2e3ebdSchin					munmap(mm, MAPSIZE);
104da2e3ebdSchin				mm = (caddr_t)mmap((caddr_t)0, MAPSIZE,
105da2e3ebdSchin					(PROT_READ|PROT_WRITE),
106da2e3ebdSchin					(MAP_PRIVATE|MAP_VARIABLE),
107da2e3ebdSchin					fd, i*MAPSIZE );
108da2e3ebdSchin			}
109da2e3ebdSchin			if(mm == (caddr_t)(-1) || mm == (caddr_t)0)
110da2e3ebdSchin				return Failed(file);
111da2e3ebdSchin		}
112da2e3ebdSchin		times(&etm);
113da2e3ebdSchin		close(fd);
114da2e3ebdSchin		remove(file);
115da2e3ebdSchin		mmtm = (etm.tms_utime-stm.tms_utime) + (etm.tms_stime-stm.tms_stime);
116da2e3ebdSchin
117da2e3ebdSchin		return rdtm+60 < mmtm ? 1 : 0;
118da2e3ebdSchin	}
119da2e3ebdSchin}end
120da2e3ebdSchin
121da2e3ebdSchintst	lib_mmap64 -D_LARGEFILE64_SOURCE note{ mmap64 interface and implementation work }end execute{
122da2e3ebdSchin	#if !_lib_mmap
123da2e3ebdSchin	(
124da2e3ebdSchin	#endif
125da2e3ebdSchin
126da2e3ebdSchin	#include <unistd.h>
127da2e3ebdSchin	#include <fcntl.h>
128da2e3ebdSchin	#include <sys/types.h>
129da2e3ebdSchin	#include <sys/mman.h>
130da2e3ebdSchin	#include <sys/stat.h>
131da2e3ebdSchin
132da2e3ebdSchin	int
133da2e3ebdSchin	main()
134da2e3ebdSchin	{
135da2e3ebdSchin	        off64_t         off;
136da2e3ebdSchin	        int             fd;
137da2e3ebdSchin	        int             n;
138da2e3ebdSchin	        char*           s;
139da2e3ebdSchin		struct stat64	st;
140da2e3ebdSchin	        char            file[32] = {'/','t','m','p','/','m','m','X','X','X','X','X','X'};
141da2e3ebdSchin
142da2e3ebdSchin		/* hey, stubs are supposed to fail! */
143da2e3ebdSchin		if (stat64(".", &st) || !st.st_mode || !st.st_mtime)
144da2e3ebdSchin			return 1;
145da2e3ebdSchin	        if (!mktemp(file) || (fd = open64(file, O_CREAT|O_WRONLY, 0600)) < 0)
146da2e3ebdSchin	        {
147da2e3ebdSchin	                remove(file);
148da2e3ebdSchin	                return 1;
149da2e3ebdSchin	        }
150da2e3ebdSchin	        off = (1<<8);
151da2e3ebdSchin	        off *= off;
152da2e3ebdSchin	        if (lseek64(fd, off, SEEK_SET) != off)
153da2e3ebdSchin	        {
154da2e3ebdSchin	                remove(file);
155da2e3ebdSchin	                return 1;
156da2e3ebdSchin	        }
157da2e3ebdSchin	        n = strlen(file) + 1;
158da2e3ebdSchin	        if (write(fd, file, n) != n)
159da2e3ebdSchin	        {
160da2e3ebdSchin	                remove(file);
161da2e3ebdSchin	                return 1;
162da2e3ebdSchin	        }
163da2e3ebdSchin	        if (close(fd) < 0 || (fd = open64(file, O_RDWR)) < 0)
164da2e3ebdSchin	        {
165da2e3ebdSchin	                remove(file);
166da2e3ebdSchin	                return 1;
167da2e3ebdSchin	        }
168da2e3ebdSchin	        if (!(s = mmap64((caddr_t)0, (size_t)n, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, off)))
169da2e3ebdSchin	        {
170da2e3ebdSchin	                remove(file);
171da2e3ebdSchin	                return 1;
172da2e3ebdSchin	        }
173da2e3ebdSchin	        if (strcmp(s, file))
174da2e3ebdSchin	        {
175da2e3ebdSchin	                remove(file);
176da2e3ebdSchin	                return 1;
177da2e3ebdSchin	        }
178da2e3ebdSchin	        close(fd);
179da2e3ebdSchin	        remove(file);
180da2e3ebdSchin	        return 0;
181da2e3ebdSchin	}
182da2e3ebdSchin}end
183da2e3ebdSchin
184da2e3ebdSchintst	mmap_anon note{ use mmap MAP_ANON to get raw memory }end execute{
185da2e3ebdSchin	#if !_lib_mmap
186da2e3ebdSchin	(
187da2e3ebdSchin	#endif
188da2e3ebdSchin	#include <unistd.h>
189da2e3ebdSchin	#include <fcntl.h>
190da2e3ebdSchin	#include <sys/types.h>
191da2e3ebdSchin	#include <sys/mman.h>
192da2e3ebdSchin	#if defined(MAP_ANONYMOUS) && !defined(MAP_ANON)
193da2e3ebdSchin	#define MAP_ANON	MAP_ANONYMOUS
194da2e3ebdSchin	#endif
195da2e3ebdSchin	int
196da2e3ebdSchin	main()
197da2e3ebdSchin	{	void	*addr;
198da2e3ebdSchin		addr = mmap(0,1024*1024,PROT_READ|PROT_WRITE,MAP_ANON|MAP_PRIVATE,-1,0);
199da2e3ebdSchin		return (addr && addr != (void*)(-1)) ? 0 : 1;
200da2e3ebdSchin	}
201da2e3ebdSchin}end
202da2e3ebdSchin
203da2e3ebdSchintst	mmap_devzero note{ use mmap on /dev/zero to get raw memory }end execute{
204da2e3ebdSchin	#if !_lib_mmap
205da2e3ebdSchin	(
206da2e3ebdSchin	#endif
207da2e3ebdSchin	#include <unistd.h>
208da2e3ebdSchin	#include <fcntl.h>
209da2e3ebdSchin	#include <sys/types.h>
210da2e3ebdSchin	#include <sys/mman.h>
211da2e3ebdSchin	int
212da2e3ebdSchin	main()
213da2e3ebdSchin	{	int	fd;
214da2e3ebdSchin		void	*addr;
215da2e3ebdSchin		if((fd = open("/dev/zero", O_RDWR)) < 0)
216da2e3ebdSchin			return 1;
217da2e3ebdSchin		addr = mmap(0,1024*1024,PROT_READ|PROT_WRITE,MAP_PRIVATE,fd,0);
218da2e3ebdSchin		return (addr && addr != (void*)(-1)) ? 0 : 1;
219da2e3ebdSchin	}
220da2e3ebdSchin}end
221da2e3ebdSchin
222da2e3ebdSchintst	note{ mmap is worth using }end output{
223da2e3ebdSchin	#if !_lib_mmap
224da2e3ebdSchin	(
225da2e3ebdSchin	#endif
226da2e3ebdSchin	#include <unistd.h>
227da2e3ebdSchin	#include <fcntl.h>
228da2e3ebdSchin	#include <sys/types.h>
229da2e3ebdSchin	#include <sys/mman.h>
230da2e3ebdSchin	#include <sys/stat.h>
231da2e3ebdSchin	#include <sys/times.h>
232da2e3ebdSchin
233da2e3ebdSchin	#define MAPSIZE (64*1024)
234da2e3ebdSchin	#define BUFSIZE	(MAPSIZE/8)
235da2e3ebdSchin	#define WRITE   (64)
236da2e3ebdSchin	#define RUN	(64)
237da2e3ebdSchin
238da2e3ebdSchin	#define Failed(file)	(remove(file),1)
239da2e3ebdSchin
240da2e3ebdSchin	int
241da2e3ebdSchin	#if _STD_
242da2e3ebdSchin	main(int argc, char** argv)
243da2e3ebdSchin	#else
244da2e3ebdSchin	main(argc,argv)
245da2e3ebdSchin	int     argc;
246da2e3ebdSchin	char**  argv;
247da2e3ebdSchin	#endif
248da2e3ebdSchin	{
249da2e3ebdSchin		caddr_t		mm;
250da2e3ebdSchin		char		*t, *f;
251da2e3ebdSchin		int		i, fd, k, run;
252da2e3ebdSchin		char		file[1024], buf[MAPSIZE];
253da2e3ebdSchin		struct tms	stm, etm;
254da2e3ebdSchin		clock_t		rdtm, mmtm;
255da2e3ebdSchin
256da2e3ebdSchin		/* create data file */
257da2e3ebdSchin		f = argv[0]; t = file;
258da2e3ebdSchin		while (*t = *f++)
259da2e3ebdSchin			t++;
260da2e3ebdSchin		*t++ = '.'; *t++ = 'D'; *t = 0;
261da2e3ebdSchin		if ((fd = open(file, O_CREAT|O_TRUNC|O_WRONLY, 0666)) < 0)
262da2e3ebdSchin			return 1;
263da2e3ebdSchin
264da2e3ebdSchin		for (i = 0; i < sizeof(buf); ++i)
265da2e3ebdSchin			buf[i] = '0' + (i%10);
266da2e3ebdSchin		for (i = 0; i < WRITE; ++i)
267da2e3ebdSchin			if (write(fd,buf,sizeof(buf)) != sizeof(buf))
268da2e3ebdSchin				return Failed(file);
269da2e3ebdSchin		close(fd);
270da2e3ebdSchin
271da2e3ebdSchin		/* read time */
272da2e3ebdSchin		times(&stm);
273da2e3ebdSchin		for(run = 0; run < RUN; ++run)
274da2e3ebdSchin		{	if((fd = open(file, O_RDWR)) < 0)
275da2e3ebdSchin				return Failed(file);
276da2e3ebdSchin			for (i = 0; i < WRITE; ++i)
277da2e3ebdSchin			{	for(k = 0; k < MAPSIZE; k += BUFSIZE)
278da2e3ebdSchin					if (read(fd,buf,BUFSIZE) != BUFSIZE)
279da2e3ebdSchin						return Failed(file);
280da2e3ebdSchin			}
281da2e3ebdSchin			close(fd);
282da2e3ebdSchin		}
283da2e3ebdSchin		times(&etm);
284da2e3ebdSchin		rdtm = (etm.tms_utime-stm.tms_utime) + (etm.tms_stime-stm.tms_stime);
285da2e3ebdSchin
286da2e3ebdSchin		/* mmap time */
287da2e3ebdSchin		times(&stm);
288da2e3ebdSchin		for(run = 0; run < RUN; ++run)
289da2e3ebdSchin		{	if ((fd = open(file, O_RDWR)) < 0)
290da2e3ebdSchin				return Failed(file);
291da2e3ebdSchin			for(i = 0, mm = (caddr_t)0; i < WRITE; ++i)
292da2e3ebdSchin			{	if(mm)
293da2e3ebdSchin					munmap(mm, MAPSIZE);
294da2e3ebdSchin				mm = (caddr_t)mmap((caddr_t)0, MAPSIZE,
295da2e3ebdSchin						   (PROT_READ|PROT_WRITE),
296da2e3ebdSchin						   MAP_PRIVATE, fd, i*MAPSIZE );
297da2e3ebdSchin				if(mm == (caddr_t)(-1) || mm == (caddr_t)0)
298da2e3ebdSchin					return Failed(file);
299da2e3ebdSchin
300da2e3ebdSchin				/* the memcpy is < BUFSIZE to simulate the
301da2e3ebdSchin				   fact that functions like sfreserve/sfgetr do
302da2e3ebdSchin				   not do buffer copying.
303da2e3ebdSchin				*/
304da2e3ebdSchin				t = (char*)mm;
305da2e3ebdSchin				for(k = 0; k < MAPSIZE; k += BUFSIZE, t += BUFSIZE)
306da2e3ebdSchin					memcpy(buf,t,(3*BUFSIZE)/4);
307da2e3ebdSchin			}
308da2e3ebdSchin			close(fd);
309da2e3ebdSchin		}
310da2e3ebdSchin		times(&etm);
311da2e3ebdSchin		mmtm = (etm.tms_utime-stm.tms_utime) + (etm.tms_stime-stm.tms_stime);
312da2e3ebdSchin
313da2e3ebdSchin		remove(file);
314da2e3ebdSchin
315da2e3ebdSchin		if(4*mmtm <= 3*rdtm)
316da2e3ebdSchin			printf("#define _mmap_worthy	2	/* mmap is great */\n");
317da2e3ebdSchin		else if(4*mmtm <= 5*rdtm)
318da2e3ebdSchin			printf("#define _mmap_worthy	1	/* mmap is good */\n");
319da2e3ebdSchin
320da2e3ebdSchin		else
321da2e3ebdSchin			return 1;
322da2e3ebdSchin		return 0;
323da2e3ebdSchin	}
324da2e3ebdSchin}end
325da2e3ebdSchin
326da2e3ebdSchincat{
327da2e3ebdSchin
328da2e3ebdSchin	/* some systems get it wrong but escape concise detection */
329da2e3ebdSchin	#ifndef _NO_MMAP
330da2e3ebdSchin	#if __CYGWIN__
331da2e3ebdSchin	#define _NO_MMAP	1
332da2e3ebdSchin	#endif
333da2e3ebdSchin	#endif
334da2e3ebdSchin
335da2e3ebdSchin	#if _NO_MMAP
336da2e3ebdSchin	#undef	_lib_mmap
337da2e3ebdSchin	#undef	_lib_mmap64
338da2e3ebdSchin	#undef	_mmap_anon
339da2e3ebdSchin	#undef	_mmap_devzero
340da2e3ebdSchin	#undef	_mmap_worthy
341da2e3ebdSchin	#endif
342da2e3ebdSchin}end
343