1#
2# This file defines probes for local features that vmalloc requires.
3# Such probes are interpreted by the "iffe" language interpreter.
4# Results are stored in the FEATURE directory. Some of the
5# {lib,hdr,sys,typ} tests may also be done in the AST features/lib;
6# repeating them here allows for single standalone and AST sources.
7#
8
9ref	-D_def_map_ast=1
10
11lib	atexit,getpagesize,mallinfo,mallopt,memalign,mstats
12lib	onexit,pvalloc,strdup,valloc,vmalloc
13lib	_malloc,__malloc,__libc_malloc
14hdr	alloca,malloc,stat,stdlib,unistd
15mem	mallinfo.arena,mstats.bytes_total malloc.h
16sys	stat
17typ	ssize_t
18
19tst	mem_sbrk note{ brk()/sbrk() work as expected }end execute{
20	#include        <sys/types.h>
21	#include        <unistd.h>
22	#undef	uchar
23	#define	uchar	unsigned char
24	int main()
25	{	uchar	*brk0, *brk1;
26
27		/* allocate a big chunk */
28		if(!(brk0 = (uchar*)sbrk(0)) || brk0 == (uchar*)(-1))
29			return 1;
30		brk0 += 256*1024;
31		if(brk(brk0) != 0)
32			return 1;
33		if((brk1 = (uchar*)sbrk(0)) != brk0)
34			return 1;
35
36		/* now return half of it */
37		brk1 -= 128*1024;
38		if(brk(brk1) != 0 )
39			return 1;
40		if((brk0 = (uchar*)sbrk(0)) != brk1)
41			return 1;
42
43		return 0;
44	}
45}end
46
47tst	map_malloc note{ map malloc to _ast_malloc }end noexecute{
48	#if __CYGWIN__
49	int main() { return 1; }
50	#else
51	static int user = 0;
52	_BEGIN_EXTERNS_
53	#if _lib_strdup
54	extern char* strdup _ARG_((const char*));
55	#define LOCAL()	strdup("s")
56	#else
57	extern void* calloc _ARG_((unsigned int, unsigned int));
58	#define LOCAL()	calloc(1,1)
59	#endif
60	#if __CYGWIN__
61	#define extern __declspec(dllexport)
62	#endif
63	#define HT double
64	static HT heap[1024 * 4];
65	static HT* hp = &heap[1];
66	static HT* op;
67	#define MALLOC(n) if(user)return&heap[0];op=hp;hp+=(n+sizeof(HT)-1)/sizeof(HT);return(void*)op;
68	#define INTERCEPTED(p) (((char*)(p))==((char*)&heap[0]))
69	#if _STD_
70	extern void free(void* p) { }
71	extern void _free(void* p) { }
72	extern void __free(void* p) { }
73	extern void __libc_free(void* p) { }
74	extern void* malloc(unsigned int n) { MALLOC(n); }
75	extern void* _malloc(unsigned int n) { MALLOC(n); }
76	extern void* __malloc(unsigned int n) { MALLOC(n); }
77	extern void* __libc_malloc(unsigned int n) { MALLOC(n); }
78	#else
79	extern void free(p) char* p; { }
80	extern void _free(p) char* p; { }
81	extern void __free(p) char* p; { }
82	extern void __libc_free(p) char* p; { }
83	extern void* malloc(n) unsigned int n; { MALLOC(n); }
84	extern void* _malloc(n) unsigned int n; { MALLOC(n); }
85	extern void* __malloc(n) unsigned int n; { MALLOC(n); }
86	extern void* __libc_malloc(n) unsigned int n; { MALLOC(n); }
87	#endif
88	_END_EXTERNS_
89	int main() { user = 1; return !INTERCEPTED(LOCAL()); }
90	#endif
91}end
92
93tst	map_malloc note{ map malloc to _ast_malloc -- wimp-o mach? }end noexecute{
94	#if _map_malloc
95	int main() { return 0; }
96	#else
97	_BEGIN_EXTERNS_
98	#if _STD_
99	void* calloc(unsigned n, unsigned m) { exit(1); }
100	#else
101	void* calloc(n, m) unsigned n, m; { exit(1); }
102	#endif
103	_END_EXTERNS_
104	int main() { return 0; }
105	#endif
106}end
107
108lib	alloca note{ alloca exists }end link{
109	#if _hdr_alloca
110	#include	<alloca.h>
111	#endif
112	int
113	main()
114	{	alloca(10);
115	}
116}end
117
118tst	mal_alloca note{ alloca is based on malloc() }end execute{
119	#if __CYGWIN__
120	int main() { return 1; }
121	#else
122	#if _hdr_alloca
123	#include	<alloca.h>
124	#endif
125	#if _STD_
126	void* malloc(unsigned int size)
127	#else
128	void* malloc(size) unsigned int size;
129	#endif
130	{	exit(0);
131		return 0;
132	}
133	int main()
134	{	alloca(10);
135		return 1;
136	}
137	#endif
138}end
139
140tst	stk_down note{ stack grows downward }end execute{
141	static growdown()
142	{	static char*	addr = 0;
143		char		array[4];
144		if(!addr)
145		{	addr = &array[0];
146			return growdown();
147		}
148		else if(addr < &array[0])
149			return 0;
150		else	return 1;
151	}
152	int main() { return growdown() ? 0 : 1; }
153}end
154
155tst	malloc_hook note{ gnu malloc hooks work }end execute{
156	#include <malloc.h>
157
158	static int      	test_free_hit = 0;
159	static int      	test_malloc_hit = 0;
160	static int      	test_memalign_hit = 0;
161	static int      	test_realloc_hit = 0;
162
163	static void test_free_hook(void* ptr, const void* caller)
164	{
165	        test_free_hit++;
166	}
167
168	static void* test_malloc_hook(size_t size, const void* caller)
169	{
170	        test_malloc_hit++;
171	        return 0;
172	}
173
174	static void* test_memalign_hook(size_t align, size_t size, const void* caller)
175	{
176	        test_memalign_hit++;
177	        return 0;
178	}
179
180	static void* test_realloc_hook(void* ptr, size_t size, const void* caller)
181	{
182	        test_realloc_hit++;
183	        return 0;
184	}
185
186	static void test_initialize_hook(void)
187	{
188	        __free_hook = test_free_hook;
189	        __malloc_hook = test_malloc_hook;
190	        __memalign_hook = test_memalign_hook;
191	        __realloc_hook = test_realloc_hook;
192	}
193
194	void    (*__malloc_initialize_hook)(void) = test_initialize_hook;
195
196	int main()
197	{
198	        void*   p;
199
200	        p = malloc(16);
201	        p = realloc(p, 32);
202	        free(p);
203	        p = memalign(32, 32);
204	        return !test_free_hit || !test_malloc_hit || !test_memalign_hit || !test_realloc_hit;
205	}
206}end
207
208cat{
209	#include "FEATURE/mmap"
210	#if _BLD_INSTRUMENT || cray || _UWIN && _BLD_ast
211	#undef	_map_malloc
212	#define _std_malloc	1	/* defer to standard malloc */
213	#endif
214	#if _mmap_anon
215	#define _mem_mmap_anon	1
216	#endif
217	#if _mmap_devzero
218	#define _mem_mmap_zero	1
219	#endif
220}end
221