]>
git.saurik.com Git - apple/xnu.git/blob - tools/tests/xnu_quick_test/memory_tests.c
c14564a32ebd27590395713e71268a20d7b51e4a
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
];
16 * static to localize to this compilation unit; volatile to avoid register
17 * optimization which would prevent modification by a signal handler.
19 static volatile int my_err
;
22 bus_handler(int sig
, siginfo_t
*si
, void *mcontext
)
24 /* Reset global error value when we see a SIGBUS */
30 /* **************************************************************************************************************
31 * Test madvise, mincore, minherit, mlock, mlock, mmap, mprotect, msync, munmap system calls.
32 * todo - see if Francois has better versions of these tests...
33 * **************************************************************************************************************
35 int memory_tests( void * the_argp
)
37 int my_page_size
, my_status
;
39 char * my_pathp
= NULL
;
40 char * my_bufp
= NULL
;
41 char * my_addr
= NULL
;
42 char * my_test_page_p
= NULL
;
44 pid_t my_pid
, my_wait_pid
;
46 struct sigaction my_sa
;
48 my_kr
= vm_allocate((vm_map_t
) mach_task_self(), (vm_address_t
*)&my_pathp
, PATH_MAX
, VM_FLAGS_ANYWHERE
);
49 if(my_kr
!= KERN_SUCCESS
){
50 printf( "vm_allocate failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
51 goto test_failed_exit
;
55 strcat( my_pathp
, &g_target_path
[0] );
56 strcat( my_pathp
, "/" );
58 /* create a test file */
59 my_err
= create_random_name( my_pathp
, 1 );
61 goto test_failed_exit
;
64 my_page_size
= getpagesize( );
65 my_kr
= vm_allocate((vm_map_t
) mach_task_self(), (vm_address_t
*)&my_test_page_p
, my_page_size
, VM_FLAGS_ANYWHERE
);
66 if(my_kr
!= KERN_SUCCESS
){
67 printf( "vm_allocate failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
68 goto test_failed_exit
;
71 *my_test_page_p
= 0x00;
72 strcat( my_test_page_p
, "parent data" );
74 /* test minherit - share a page with child, add to the string in child then
75 * check for modification after child terminates.
77 my_err
= minherit( my_test_page_p
, my_page_size
, VM_INHERIT_SHARE
);
79 printf( "minherit failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
80 goto test_failed_exit
;
84 * spin off a child process that we will use for testing.
88 printf( "fork failed with errno %d - %s \n", errno
, strerror( errno
) );
89 goto test_failed_exit
;
95 strcat( my_test_page_p
, " child data" );
97 /* create a test file in page size chunks */
98 my_kr
= vm_allocate((vm_map_t
) mach_task_self(), (vm_address_t
*)&my_bufp
, (my_page_size
* 10), VM_FLAGS_ANYWHERE
);
99 if(my_kr
!= KERN_SUCCESS
){
100 printf( "vm_allocate failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
105 /* test madvise on anonymous memory */
106 my_err
= madvise(my_bufp
, (my_page_size
* 10), MADV_WILLNEED
);
107 if ( my_err
== -1 ) {
108 printf("madvise WILLNEED on anon memory failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
113 memset( my_bufp
, 'j', (my_page_size
* 10) );
114 my_fd
= open( my_pathp
, O_RDWR
, 0 );
116 printf( "open call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
121 /* test madvise on anonymous memory */
122 my_err
= madvise(my_bufp
, (my_page_size
* 10), MADV_DONTNEED
);
123 if ( my_err
== -1 ) {
124 printf("madvise DONTNEED on anon memory failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
129 my_result
= write( my_fd
, my_bufp
, (my_page_size
* 10) );
130 if ( my_result
== -1 ) {
131 printf( "write call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
136 /* map the file into memory */
137 my_addr
= (char *) mmap( NULL
, (my_page_size
* 2), (PROT_READ
| PROT_WRITE
), (MAP_FILE
| MAP_SHARED
), my_fd
, 0 );
138 if ( my_addr
== (char *) -1 ) {
139 printf( "mmap call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
144 /* make sure we got the right data mapped */
145 if ( *my_addr
!= 'j' || *(my_addr
+ my_page_size
) != 'j' ) {
146 printf( "did not map in correct data \n" );
152 my_err
= madvise( my_addr
, (my_page_size
* 2), MADV_WILLNEED
);
153 if ( my_err
== -1 ) {
154 printf( "madvise WILLNEED call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
159 my_err
= madvise( my_addr
, (my_page_size
* 2), MADV_DONTNEED
);
160 if ( my_err
== -1 ) {
161 printf( "madvise DONTNEED call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
166 /* test mincore, mlock, mlock */
167 my_err
= mlock( my_addr
, my_page_size
);
168 if ( my_err
== -1 ) {
169 printf( "mlock call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
174 /* mybufp is about to be reused, so test madvise on anonymous memory */
175 my_err
= madvise(my_bufp
, (my_page_size
* 10), MADV_FREE
);
176 if ( my_err
== -1 ) {
177 printf("madvise FREE on anon memory failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
182 my_err
= mincore( my_addr
, 1, my_bufp
);
183 if ( my_err
== -1 ) {
184 printf( "mincore call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
188 /* page my_addr is in should be resident after mlock */
189 if ( (*my_bufp
& MINCORE_INCORE
) == 0 ) {
190 printf( "mincore call failed to find resident page \n" );
195 my_err
= munlock( my_addr
, my_page_size
);
196 if ( my_err
== -1 ) {
197 printf( "munlock call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
202 /* modify first page then use msync to push data out */
203 memset( my_addr
, 'x', my_page_size
);
204 my_err
= msync( my_addr
, my_page_size
, (MS_SYNC
| MS_INVALIDATE
) );
205 if ( my_err
== -1 ) {
206 printf( "msync call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
212 my_err
= madvise( my_addr
, (my_page_size
* 2), MADV_DONTNEED
);
213 if ( my_err
== -1 ) {
214 printf( "madvise DONTNEED call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
220 my_err
= madvise( my_addr
, (my_page_size
* 2), MADV_FREE
);
221 if ( my_err
== -1 ) {
222 printf( "madvise FREE call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
227 /* verify that the file was updated */
228 lseek( my_fd
, 0, SEEK_SET
);
229 bzero( (void *)my_bufp
, my_page_size
);
230 my_result
= read( my_fd
, my_bufp
, my_page_size
);
231 if ( my_result
== -1 ) {
232 printf( "read call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
236 if ( *my_bufp
!= 'x' ) {
237 printf( "msync did not flush correct data \n" );
242 /* unmap our test page */
243 my_err
= munmap( my_addr
, (my_page_size
* 2) );
244 if ( my_err
== -1 ) {
245 printf( "munmap call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
251 /* map the file into memory again for mprotect test */
252 my_addr
= (char *) mmap( NULL
, (my_page_size
* 2), (PROT_READ
| PROT_WRITE
), (MAP_FILE
| MAP_SHARED
), my_fd
, 0 );
253 if ( my_addr
== (char *) -1 ) {
254 printf( "mmap call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
262 /* test mprotect - change protection to only PROT_READ */
263 my_err
= mprotect( my_addr
, my_page_size
, PROT_READ
);
264 if ( my_err
== -1 ) {
265 printf( "mprotect call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
270 my_sa
.sa_sigaction
= bus_handler
;
271 my_sa
.sa_flags
= SA_SIGINFO
| SA_RESETHAND
;
272 if ((my_err
= sigaction(SIGBUS
, &my_sa
, NULL
)) != 0) {
273 printf("sigaction call failed with error %d - \"%s\" \n", errno
, strerror( errno
) );
278 my_err
= -1; /* default to error out if we do NOT trigger a SIGBUS */
280 *my_addr
= 'z'; /* should cause SIGBUS signal (we look for this at child termination within the parent) */
284 printf("Expected SIGBUS signal, got nothing!\n");
291 * we should get no error if the child has completed all tests successfully
293 my_wait_pid
= wait4( my_pid
, &my_status
, 0, NULL
);
294 if ( my_wait_pid
== -1 ) {
295 printf( "wait4 failed with errno %d - %s \n", errno
, strerror( errno
) );
296 goto test_failed_exit
;
299 /* wait4 should return our child's pid when it exits */
300 if ( my_wait_pid
!= my_pid
) {
301 printf( "wait4 did not return child pid - returned %d should be %d \n", my_wait_pid
, my_pid
);
302 goto test_failed_exit
;
305 /* If we did not exit cleanly, report it
307 if ( !WIFEXITED( my_status
) || (WEXITSTATUS( my_status
) != 0)) {
308 printf( "wait4 returned child died of status - 0x%08X \n", my_status
);
309 goto test_failed_exit
;
312 /* make sure shared page got modified in child */
313 if ( strcmp( my_test_page_p
, "parent data child data" ) != 0 ) {
314 printf( "minherit did not work correctly - shared page looks wrong \n" );
315 goto test_failed_exit
;
318 goto test_passed_exit
;
324 if ( my_pathp
!= NULL
) {
326 vm_deallocate(mach_task_self(), (vm_address_t
)my_pathp
, PATH_MAX
);
328 if ( my_test_page_p
!= NULL
) {
329 vm_deallocate(mach_task_self(), (vm_address_t
)my_test_page_p
, my_page_size
);