2 //=============================================================================
4 * @file Based_Pointer_Test.cpp
6 * This test check the Based_Pointer and Based_Pointer_repository classes.
8 * @author Steve Williams <steve@telxio>
10 //=============================================================================
13 #include "test_config.h"
16 #ifdef ACE_HAS_POSITION_INDEPENDENT_POINTERS
17 #include "ace/Based_Pointer_Repository.h"
18 #endif /* ACE_HAS_POSITION_INDEPENDENT_POINTERS */
19 #include "ace/Malloc_T.h"
20 #include "ace/MMAP_Memory_Pool.h"
21 #include "ace/PI_Malloc.h"
22 #include "ace/Null_Mutex.h"
23 #include "ace/Based_Pointer_T.h"
24 #include "ace/SString.h"
25 #include "ace/OS_NS_unistd.h"
34 friend class ace_dewarn_gplusplus
;
40 class Void_Pointer
: public ACE_Based_Pointer
<void>
44 #ifdef ACE_HAS_POSITION_INDEPENDENT_POINTERS
46 #if defined (ACE_LD_DECORATOR_STR)
47 # define OBJ_SUFFIX ACE_LD_DECORATOR_STR ACE_DLL_SUFFIX
49 # define OBJ_SUFFIX ACE_DLL_SUFFIX
50 #endif /* ACE_LD_DECORATOR_STR */
52 #if defined (ACE_WIN32) || defined (ACE_OPENVMS)
53 # define OBJ_PREFIX ACE_DLL_PREFIX
55 # define OBJ_PREFIX ACE_TEXT("./") ACE_DLL_PREFIX
56 #endif /* ACE_WIN32 */
58 // Declare the type of the DLL symbol:
59 typedef void *(*Get_Bp_Repository_Inst
)(void);
61 // Declare an allocator based MMAP_Memory_Pool
62 typedef ACE_Malloc_T
< ACE_MMAP_MEMORY_POOL
, ACE_Null_Mutex
, ACE_PI_Control_Block
66 // Check that the ACE_Based_Pointer_Repository can be accessed
68 // (see http://bugzilla.dre.vanderbilt.edu/show_bug.cgi?id=1991)
69 int singleton_test (void)
71 void* baddr1
= ACE_BASED_POINTER_REPOSITORY::instance();
72 void* baddr2
= ACE_BASED_POINTER_REPOSITORY::instance();
76 ACE_ERROR_RETURN ((LM_ERROR
,
77 ACE_TEXT ("ACE_Based_Pointer_Repository is not a singleton\n")),
81 // Protection against this test being run on platforms not supporting Dlls.
82 #if defined(ACE_HAS_DYNAMIC_LINKING)
85 const char *subdir_env
= ACE_OS::getenv ("ACE_EXE_SUB_DIR");
88 dll_file
= ACE_TEXT_CHAR_TO_TCHAR (subdir_env
);
89 dll_file
+= ACE_DIRECTORY_SEPARATOR_STR
;
92 dll_file
+= OBJ_PREFIX
ACE_TEXT ("Based_Pointer_Test_Lib") OBJ_SUFFIX
;
94 // If DLL causes multiple instances of singleton
95 // then the ACE_Cleanup object registered
96 // with the ACE_Object_manager will no longer be valid,
97 // at exit time if the library is unloaded. Override
98 // the default close on destruct.
100 int retval
= dll
.open (dll_file
.c_str (),
101 ACE_DEFAULT_SHLIB_MODE
,
106 ACE_TCHAR
*dll_error
= dll
.error ();
107 ACE_ERROR_RETURN ((LM_ERROR
,
108 ACE_TEXT ("Error in DLL Open: %s\n"),
109 dll_error
? dll_error
: ACE_TEXT ("unknown error")),
113 #if defined (ACE_OPENVMS)
114 // with OPENVMS symbol names > 31 cause us trouble with dlsym()
115 void* foo
= dll
.symbol (ACE_TEXT ("get_based_pointer_repo_inst"));
117 void* foo
= dll
.symbol (ACE_TEXT ("get_based_pointer_repository_instance"));
120 // Cast the void* to function* with a long as intermediate.
121 ptrdiff_t tmp
= reinterpret_cast<ptrdiff_t> (foo
);
122 Get_Bp_Repository_Inst get_bp_repository_inst
=
123 reinterpret_cast<Get_Bp_Repository_Inst
> (tmp
);
124 if (get_bp_repository_inst
== 0)
125 ACE_ERROR_RETURN ((LM_ERROR
,
130 void* baddr_dll
= get_bp_repository_inst ();
134 if (baddr_dll
!= baddr1
)
136 ACE_ERROR_RETURN ((LM_ERROR
,
137 ACE_TEXT ("ACE_Based_Pointer_Repository is not a ")
138 ACE_TEXT ("singleton in DLL <%@> <%@>\n"),
143 #endif /* ACE_HAS_DYNAMIC_LINKING */
148 // Check that MMAP memory blocks are correctly mapped
149 // into the Based_Pointer_Repository
153 MMAP_Allocator
* alloc
= 0;
155 ACE_OS::unlink("foo");
157 // The 'options' are only here to quiet MSVC 6. It can be removed
158 // when MSVC 6 support is removed.
159 MMAP_Allocator::MEMORY_POOL_OPTIONS
*options
= 0;
162 MMAP_Allocator (ACE_TEXT ("foo"), ACE_TEXT ("foo"), options
),
165 void* addr
= alloc
->base_addr();
169 ACE_TEXT ("Unable to get base to MMAP Memory Pool\n")));
175 // Check a base address mapping was added to the Repository
176 // when the pool was created
178 if(ACE_BASED_POINTER_REPOSITORY::instance()->find(addr
, ba
) == -1)
180 ACE_ERROR((LM_ERROR
, ACE_TEXT ("Unable to access repository\n")));
191 ACE_ERROR_RETURN ((LM_ERROR
,
192 ACE_TEXT ("MMAP pool mapping not present\n")),
196 // Check Mapping is removed when object is deleted
197 if (ACE_BASED_POINTER_REPOSITORY::instance()->find(addr
, ba
) == -1)
199 ACE_ERROR_RETURN ((LM_ERROR
,
200 ACE_TEXT ("Unable to access repository\n")),
205 ACE_ERROR_RETURN ((LM_ERROR
,
206 ACE_TEXT ("MMAP pool mapping not removed\n")),
213 // Check that persistent MMAP memory blocks are correctly remapped
214 // into the Based_Pointer_Repository
215 // (i.e. maps based on backing stores that are already
216 // present in the filesystem)
217 // (see http://bugzilla.dre.vanderbilt.edu/show_bug.cgi?id=2216)
219 mmap_persistent_map_test(void)
221 MMAP_Allocator
* alloc
= 0;
223 // The 'options' are only here to quiet MSVC 6. It can be removed
224 // when MSVC 6 support is removed.
225 MMAP_Allocator::MEMORY_POOL_OPTIONS
*options
= 0;
226 ACE_OS::unlink("foo");
230 MMAP_Allocator (ACE_TEXT ("foo"), ACE_TEXT ("foo"), options
),
234 // Delete Malloc and the memory pool, but do not remove
236 alloc
->memory_pool().release(0);
240 // Recreate segment with existing backing store
244 MMAP_Allocator (ACE_TEXT ("foo"), ACE_TEXT("foo"), options
),
247 void* addr
= alloc
->base_addr();
250 ACE_ERROR ((LM_ERROR
,
251 ACE_TEXT ("Unable to get base to persistent MMAP Memory Pool\n")));
257 if(ACE_BASED_POINTER_REPOSITORY::instance()->find(addr
, ba
) == -1)
259 ACE_ERROR ((LM_ERROR
,
260 ACE_TEXT ("Unable to find base address after map of persistent segment\n")));
267 ACE_ERROR ((LM_ERROR
,
268 ACE_TEXT ("Persistent MMAP Memory Pool not mapped\n")));
279 // Check that MMAP memory blocks are correctly remapped
280 // into the Based_Pointer_Repository
281 // (i.e. when a segment is resized it may move its base address
282 // because the OS cannot fit the new segment size at the same
283 // base address, in this case the Repository must be updated)
284 // (see http://bugzilla.dre.vanderbilt.edu/show_bug.cgi?id=2218)
286 mmap_remap_test(void)
288 // Use a Position Independent memory segment
289 // because this one is going to move
291 MMAP_Allocator
*alloc
[ 3 ]= {0, 0, 0};
292 void *pool_base
[ 3 ]= {0, 0, 0};
294 // Make sure the Pool options are set to allow
295 // the segment to move
296 ACE_MMAP_Memory_Pool_Options
data_opts(
298 ACE_MMAP_Memory_Pool_Options::NEVER_FIXED
);
303 ACE_TCHAR store
[ MAXPATHLEN
+ 1 ];
304 ACE_OS::snprintf( store
, MAXPATHLEN
+ 1, ACE_TEXT("foo%d"), i
);
305 ACE_OS::unlink( store
);
307 ACE_NEW_RETURN (alloc
[ i
],
308 MMAP_Allocator (store
, store
, &data_opts
),
310 pool_base
[ i
]= alloc
[ i
]->base_addr();
313 // sort pools into base address order
316 if (pool_base
[ i
] < pool_base
[ i
+1 ])
318 void *tmp1
= pool_base
[ i
];
319 MMAP_Allocator
*tmp2
= alloc
[ i
];
320 pool_base
[ i
]= pool_base
[ i
+1 ];
321 alloc
[ i
]= alloc
[ i
+1 ];
322 pool_base
[ i
+1 ]= tmp1
;
328 // alloc[1] is now bounded, whether memory grows up or
329 // down, it will hit either alloc[0] or alloc[2] and have
332 // Calculate maximum space between base addresses
334 size_t size
= (char *) pool_base
[ 0 ] - (char *) pool_base
[ 1 ];
335 size_t tmpsize
= (char *) pool_base
[ 1 ] - (char *) pool_base
[ 2 ];
336 size
= (size
< tmpsize
) ? tmpsize
: size
;
338 // force pool to move
341 (void)alloc
[ 1 ]->malloc(size
);
342 void *nba
= alloc
[ 1 ]->base_addr();
344 if (pool_base
[ 1 ] == nba
)
346 ACE_ERROR ((LM_ERROR
,
347 ACE_TEXT ("MMAP Pool did not move base address as expected\n")));
350 alloc
[ i
]->remove();
357 if (ACE_BASED_POINTER_REPOSITORY::instance()->find(nba
, ba
) == -1)
359 ACE_ERROR ((LM_ERROR
,
360 ACE_TEXT ("Unable to find base address after remap of segment\n")));
363 alloc
[ i
]->remove();
371 ACE_ERROR ((LM_ERROR
,
372 ACE_TEXT ("New base address not mapped after MMAP remap\n")));
375 alloc
[ i
]->remove();
381 // Check old base address has been removed
382 // from the repository
383 if (ACE_BASED_POINTER_REPOSITORY::instance()->find( pool_base
[ 1 ], ba
) == -1)
385 ACE_ERROR ((LM_ERROR
,
386 ACE_TEXT ("Unable to find base address after remap of segment\n")));
389 alloc
[ i
]->remove();
395 if (ba
== pool_base
[ 1 ])
397 ACE_ERROR ((LM_ERROR
,
398 ACE_TEXT ("Old base address not removed after MMAP remap\n")));
401 alloc
[ i
]->remove();
409 alloc
[ i
]->remove();
417 run_main (int, ACE_TCHAR
*[])
419 ACE_START_TEST (ACE_TEXT ("Based_Pointer_Test"));
423 retval
+= singleton_test ();
424 retval
+= mmap_map_test();
425 retval
+= mmap_persistent_map_test();
426 retval
+= mmap_remap_test();
428 ACE_Based_Pointer_Basic
<Foo
> Foo_Ptr
;
429 ACE_UNUSED_ARG (Foo_Ptr
);
432 return retval
== 0 ? 0 : 1;
435 #else /* ! ACE_HAS_POSITION_INDEPENDENT_POINTERS */
438 run_main (int, ACE_TCHAR
*[])
440 ACE_START_TEST (ACE_TEXT ("Based_Pointer_Test"));
441 ACE_Based_Pointer_Basic
<Foo
> Foo_Ptr
;
442 ACE_UNUSED_ARG (Foo_Ptr
);
446 #endif /* ACE_HAS_POSITION_INDEPENDENT_POINTERS */