]>
git.saurik.com Git - apple/xnu.git/blob - tools/tests/xnu_quick_test/memory_tests.c
5 * Created by Jerry Cottingham on 4/12/05.
6 * Copyright 2005 Apple Computer Inc. All rights reserved.
11 #include <mach/mach.h>
13 extern char g_target_path
[ PATH_MAX
];
15 /* **************************************************************************************************************
16 * Test madvise, mincore, minherit, mlock, mlock, mmap, mprotect, msync, munmap system calls.
17 * todo - see if Francois has better versions of these tests...
18 * **************************************************************************************************************
20 int memory_tests( void * the_argp
)
23 int my_page_size
, my_status
;
25 char * my_pathp
= NULL
;
26 char * my_bufp
= NULL
;
27 char * my_addr
= NULL
;
28 char * my_test_page_p
= NULL
;
30 pid_t my_pid
, my_wait_pid
;
33 my_kr
= vm_allocate((vm_map_t
) mach_task_self(), (vm_address_t
*)&my_pathp
, PATH_MAX
, VM_FLAGS_ANYWHERE
);
34 if(my_kr
!= KERN_SUCCESS
){
35 printf( "vm_allocate failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
36 goto test_failed_exit
;
40 strcat( my_pathp
, &g_target_path
[0] );
41 strcat( my_pathp
, "/" );
43 /* create a test file */
44 my_err
= create_random_name( my_pathp
, 1 );
46 goto test_failed_exit
;
49 my_page_size
= getpagesize( );
50 my_kr
= vm_allocate((vm_map_t
) mach_task_self(), (vm_address_t
*)&my_test_page_p
, my_page_size
, VM_FLAGS_ANYWHERE
);
51 if(my_kr
!= KERN_SUCCESS
){
52 printf( "vm_allocate failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
53 goto test_failed_exit
;
56 *my_test_page_p
= 0x00;
57 strcat( my_test_page_p
, "parent data" );
59 /* test minherit - share a page with child, add to the string in child then
60 * check for modification after child terminates.
62 my_err
= minherit( my_test_page_p
, my_page_size
, VM_INHERIT_SHARE
);
64 printf( "minherit failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
65 goto test_failed_exit
;
69 * spin off a child process that we will use for testing.
73 printf( "fork failed with errno %d - %s \n", errno
, strerror( errno
) );
74 goto test_failed_exit
;
80 strcat( my_test_page_p
, " child data" );
82 /* create a test file in page size chunks */
83 my_kr
= vm_allocate((vm_map_t
) mach_task_self(), (vm_address_t
*)&my_bufp
, (my_page_size
* 10), VM_FLAGS_ANYWHERE
);
84 if(my_kr
!= KERN_SUCCESS
){
85 printf( "vm_allocate failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
90 /* test madvise on anonymous memory */
91 my_err
= madvise(my_bufp
, (my_page_size
* 10), MADV_WILLNEED
);
93 printf("madvise WILLNEED on anon memory failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
98 memset( my_bufp
, 'j', (my_page_size
* 10) );
99 my_fd
= open( my_pathp
, O_RDWR
, 0 );
101 printf( "open call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
106 /* test madvise on anonymous memory */
107 my_err
= madvise(my_bufp
, (my_page_size
* 10), MADV_DONTNEED
);
108 if ( my_err
== -1 ) {
109 printf("madvise DONTNEED on anon memory failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
114 my_result
= write( my_fd
, my_bufp
, (my_page_size
* 10) );
115 if ( my_result
== -1 ) {
116 printf( "write call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
121 /* map the file into memory */
122 my_addr
= (char *) mmap( NULL
, (my_page_size
* 2), (PROT_READ
| PROT_WRITE
), (MAP_FILE
| MAP_SHARED
), my_fd
, 0 );
123 if ( my_addr
== (char *) -1 ) {
124 printf( "mmap call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
129 /* make sure we got the right data mapped */
130 if ( *my_addr
!= 'j' || *(my_addr
+ my_page_size
) != 'j' ) {
131 printf( "did not map in correct data \n" );
137 my_err
= madvise( my_addr
, (my_page_size
* 2), MADV_WILLNEED
);
138 if ( my_err
== -1 ) {
139 printf( "madvise WILLNEED call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
144 my_err
= madvise( my_addr
, (my_page_size
* 2), MADV_DONTNEED
);
145 if ( my_err
== -1 ) {
146 printf( "madvise DONTNEED call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
151 /* test mincore, mlock, mlock */
152 my_err
= mlock( my_addr
, my_page_size
);
153 if ( my_err
== -1 ) {
154 printf( "mlock call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
159 /* mybufp is about to be reused, so test madvise on anonymous memory */
160 my_err
= madvise(my_bufp
, (my_page_size
* 10), MADV_FREE
);
161 if ( my_err
== -1 ) {
162 printf("madvise FREE on anon memory failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
167 my_err
= mincore( my_addr
, 1, my_bufp
);
168 if ( my_err
== -1 ) {
169 printf( "mincore call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
173 /* page my_addr is in should be resident after mlock */
174 if ( (*my_bufp
& MINCORE_INCORE
) == 0 ) {
175 printf( "mincore call failed to find resident page \n" );
180 my_err
= munlock( my_addr
, my_page_size
);
181 if ( my_err
== -1 ) {
182 printf( "munlock call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
187 /* modify first page then use msync to push data out */
188 memset( my_addr
, 'x', my_page_size
);
189 my_err
= msync( my_addr
, my_page_size
, (MS_SYNC
| MS_INVALIDATE
) );
190 if ( my_err
== -1 ) {
191 printf( "msync call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
197 my_err
= madvise( my_addr
, (my_page_size
* 2), MADV_DONTNEED
);
198 if ( my_err
== -1 ) {
199 printf( "madvise DONTNEED call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
205 my_err
= madvise( my_addr
, (my_page_size
* 2), MADV_FREE
);
206 if ( my_err
== -1 ) {
207 printf( "madvise FREE call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
212 /* verify that the file was updated */
213 lseek( my_fd
, 0, SEEK_SET
);
214 bzero( (void *)my_bufp
, my_page_size
);
215 my_result
= read( my_fd
, my_bufp
, my_page_size
);
216 if ( my_result
== -1 ) {
217 printf( "read call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
221 if ( *my_bufp
!= 'x' ) {
222 printf( "msync did not flush correct data \n" );
227 /* unmap our test page */
228 my_err
= munmap( my_addr
, (my_page_size
* 2) );
229 if ( my_err
== -1 ) {
230 printf( "munmap call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
236 /* map the file into memory again for mprotect test */
237 my_addr
= (char *) mmap( NULL
, (my_page_size
* 2), (PROT_READ
| PROT_WRITE
), (MAP_FILE
| MAP_SHARED
), my_fd
, 0 );
238 if ( my_addr
== (char *) -1 ) {
239 printf( "mmap call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
247 /* test mprotect - change protection to only PROT_READ */
248 my_err
= mprotect( my_addr
, my_page_size
, PROT_READ
);
249 if ( my_err
== -1 ) {
250 printf( "mprotect call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
255 *my_addr
= 'z'; /* should cause SIGBUS signal (we look for this at child termination within the parent) */
266 * we should get SIGBUS exit when child tries to write to read only memory
268 my_wait_pid
= wait4( my_pid
, &my_status
, 0, NULL
);
269 if ( my_wait_pid
== -1 ) {
270 printf( "wait4 failed with errno %d - %s \n", errno
, strerror( errno
) );
271 goto test_failed_exit
;
274 /* wait4 should return our child's pid when it exits */
275 if ( my_wait_pid
!= my_pid
) {
276 printf( "wait4 did not return child pid - returned %d should be %d \n", my_wait_pid
, my_pid
);
277 goto test_failed_exit
;
280 if ( WIFSIGNALED( my_status
) && WTERMSIG( my_status
) != SIGBUS
) {
281 printf( "wait4 returned wrong signal status - 0x%02X \n", my_status
);
282 goto test_failed_exit
;
285 /* make sure shared page got modified in child */
286 if ( strcmp( my_test_page_p
, "parent data child data" ) != 0 ) {
287 printf( "minherit did not work correctly - shared page looks wrong \n" );
288 goto test_failed_exit
;
291 goto test_passed_exit
;
297 if ( my_pathp
!= NULL
) {
299 vm_deallocate(mach_task_self(), (vm_address_t
)my_pathp
, PATH_MAX
);
301 if ( my_test_page_p
!= NULL
) {
302 vm_deallocate(mach_task_self(), (vm_address_t
)my_test_page_p
, my_page_size
);