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