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