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)
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 using Get_Bp_Repository_Inst
= void *(*)();
61 // Declare an allocator based MMAP_Memory_Pool
62 using MMAP_Allocator
= ACE_Malloc_T
<ACE_MMAP_Memory_Pool
, ACE_Null_Mutex
, ACE_PI_Control_Block
>;
65 // Check that the ACE_Based_Pointer_Repository can be accessed
67 // (see http://bugzilla.dre.vanderbilt.edu/show_bug.cgi?id=1991)
70 void* baddr1
= ACE_BASED_POINTER_REPOSITORY::instance();
71 void* baddr2
= ACE_BASED_POINTER_REPOSITORY::instance();
75 ACE_ERROR_RETURN ((LM_ERROR
,
76 ACE_TEXT ("ACE_Based_Pointer_Repository is not a singleton\n")),
80 // Protection against this test being run on platforms not supporting Dlls.
81 #if defined(ACE_HAS_DYNAMIC_LINKING)
83 const char *subdir_env
= ACE_OS::getenv ("ACE_EXE_SUB_DIR");
86 dll_file
= ACE_TEXT_CHAR_TO_TCHAR (subdir_env
);
87 dll_file
+= ACE_DIRECTORY_SEPARATOR_STR
;
90 dll_file
+= OBJ_PREFIX
ACE_TEXT ("Based_Pointer_Test_Lib") OBJ_SUFFIX
;
92 // If DLL causes multiple instances of singleton
93 // then the ACE_Cleanup object registered
94 // with the ACE_Object_manager will no longer be valid,
95 // at exit time if the library is unloaded. Override
96 // the default close on destruct.
98 int retval
= dll
.open (dll_file
.c_str (),
99 ACE_DEFAULT_SHLIB_MODE
,
104 ACE_TCHAR
*dll_error
= dll
.error ();
105 ACE_ERROR_RETURN ((LM_ERROR
,
106 ACE_TEXT ("Error in DLL Open: %s\n"),
107 dll_error
? dll_error
: ACE_TEXT ("unknown error")),
111 void* foo
= dll
.symbol (ACE_TEXT ("get_based_pointer_repository_instance"));
113 // Cast the void* to function* with a long as intermediate.
114 ptrdiff_t tmp
= reinterpret_cast<ptrdiff_t> (foo
);
115 Get_Bp_Repository_Inst get_bp_repository_inst
=
116 reinterpret_cast<Get_Bp_Repository_Inst
> (tmp
);
117 if (get_bp_repository_inst
== 0)
118 ACE_ERROR_RETURN ((LM_ERROR
,
123 void* baddr_dll
= get_bp_repository_inst ();
127 if (baddr_dll
!= baddr1
)
129 ACE_ERROR_RETURN ((LM_ERROR
,
130 ACE_TEXT ("ACE_Based_Pointer_Repository is not a ")
131 ACE_TEXT ("singleton in DLL <%@> <%@>\n"),
136 #endif /* ACE_HAS_DYNAMIC_LINKING */
141 // Check that MMAP memory blocks are correctly mapped
142 // into the Based_Pointer_Repository
146 MMAP_Allocator
* alloc
= 0;
148 ACE_OS::unlink("foo");
150 // The 'options' are only here to quiet MSVC 6. It can be removed
151 // when MSVC 6 support is removed.
152 MMAP_Allocator::MEMORY_POOL_OPTIONS
*options
= 0;
155 MMAP_Allocator (ACE_TEXT ("foo"), ACE_TEXT ("foo"), options
),
158 void* addr
= alloc
->base_addr();
162 ACE_TEXT ("Unable to get base to MMAP Memory Pool\n")));
168 // Check a base address mapping was added to the Repository
169 // when the pool was created
171 if(ACE_BASED_POINTER_REPOSITORY::instance()->find(addr
, ba
) == -1)
173 ACE_ERROR((LM_ERROR
, ACE_TEXT ("Unable to access repository\n")));
184 ACE_ERROR_RETURN ((LM_ERROR
,
185 ACE_TEXT ("MMAP pool mapping not present\n")),
189 // Check Mapping is removed when object is deleted
190 if (ACE_BASED_POINTER_REPOSITORY::instance()->find(addr
, ba
) == -1)
192 ACE_ERROR_RETURN ((LM_ERROR
,
193 ACE_TEXT ("Unable to access repository\n")),
198 ACE_ERROR_RETURN ((LM_ERROR
,
199 ACE_TEXT ("MMAP pool mapping not removed\n")),
206 // Check that persistent MMAP memory blocks are correctly remapped
207 // into the Based_Pointer_Repository
208 // (i.e. maps based on backing stores that are already
209 // present in the filesystem)
210 // (see http://bugzilla.dre.vanderbilt.edu/show_bug.cgi?id=2216)
212 mmap_persistent_map_test()
214 MMAP_Allocator
* alloc
= 0;
216 // The 'options' are only here to quiet MSVC 6. It can be removed
217 // when MSVC 6 support is removed.
218 MMAP_Allocator::MEMORY_POOL_OPTIONS
*options
= 0;
219 ACE_OS::unlink("foo");
223 MMAP_Allocator (ACE_TEXT ("foo"), ACE_TEXT ("foo"), options
),
227 // Delete Malloc and the memory pool, but do not remove
229 alloc
->memory_pool().release(0);
233 // Recreate segment with existing backing store
237 MMAP_Allocator (ACE_TEXT ("foo"), ACE_TEXT("foo"), options
),
240 void* addr
= alloc
->base_addr();
243 ACE_ERROR ((LM_ERROR
,
244 ACE_TEXT ("Unable to get base to persistent MMAP Memory Pool\n")));
250 if(ACE_BASED_POINTER_REPOSITORY::instance()->find(addr
, ba
) == -1)
252 ACE_ERROR ((LM_ERROR
,
253 ACE_TEXT ("Unable to find base address after map of persistent segment\n")));
260 ACE_ERROR ((LM_ERROR
,
261 ACE_TEXT ("Persistent MMAP Memory Pool not mapped\n")));
272 // Check that MMAP memory blocks are correctly remapped
273 // into the Based_Pointer_Repository
274 // (i.e. when a segment is resized it may move its base address
275 // because the OS cannot fit the new segment size at the same
276 // base address, in this case the Repository must be updated)
277 // (see http://bugzilla.dre.vanderbilt.edu/show_bug.cgi?id=2218)
281 // Use a Position Independent memory segment
282 // because this one is going to move
284 MMAP_Allocator
*alloc
[ 3 ]= {0, 0, 0};
285 void *pool_base
[ 3 ]= {0, 0, 0};
287 // Make sure the Pool options are set to allow
288 // the segment to move
289 ACE_MMAP_Memory_Pool_Options
data_opts(
291 ACE_MMAP_Memory_Pool_Options::NEVER_FIXED
);
296 ACE_TCHAR store
[ MAXPATHLEN
+ 1 ];
297 ACE_OS::snprintf( store
, MAXPATHLEN
+ 1, ACE_TEXT("foo%d"), i
);
298 ACE_OS::unlink( store
);
300 ACE_NEW_RETURN (alloc
[ i
],
301 MMAP_Allocator (store
, store
, &data_opts
),
303 pool_base
[ i
]= alloc
[ i
]->base_addr();
306 // sort pools into base address order
309 if (pool_base
[ i
] < pool_base
[ i
+1 ])
311 void *tmp1
= pool_base
[ i
];
312 MMAP_Allocator
*tmp2
= alloc
[ i
];
313 pool_base
[ i
]= pool_base
[ i
+1 ];
314 alloc
[ i
]= alloc
[ i
+1 ];
315 pool_base
[ i
+1 ]= tmp1
;
321 // alloc[1] is now bounded, whether memory grows up or
322 // down, it will hit either alloc[0] or alloc[2] and have
325 // Calculate maximum space between base addresses
327 size_t size
= (char *) pool_base
[ 0 ] - (char *) pool_base
[ 1 ];
328 size_t tmpsize
= (char *) pool_base
[ 1 ] - (char *) pool_base
[ 2 ];
329 size
= (size
< tmpsize
) ? tmpsize
: size
;
331 // force pool to move
334 (void)alloc
[ 1 ]->malloc(size
);
335 void *nba
= alloc
[ 1 ]->base_addr();
337 if (pool_base
[ 1 ] == nba
)
339 ACE_ERROR ((LM_ERROR
,
340 ACE_TEXT ("MMAP Pool did not move base address as expected\n")));
343 alloc
[ i
]->remove();
350 if (ACE_BASED_POINTER_REPOSITORY::instance()->find(nba
, ba
) == -1)
352 ACE_ERROR ((LM_ERROR
,
353 ACE_TEXT ("Unable to find base address after remap of segment\n")));
356 alloc
[ i
]->remove();
364 ACE_ERROR ((LM_ERROR
,
365 ACE_TEXT ("New base address not mapped after MMAP remap\n")));
368 alloc
[ i
]->remove();
374 // Check old base address has been removed
375 // from the repository
376 if (ACE_BASED_POINTER_REPOSITORY::instance()->find( pool_base
[ 1 ], ba
) == -1)
378 ACE_ERROR ((LM_ERROR
,
379 ACE_TEXT ("Unable to find base address after remap of segment\n")));
382 alloc
[ i
]->remove();
388 if (ba
== pool_base
[ 1 ])
390 ACE_ERROR ((LM_ERROR
,
391 ACE_TEXT ("Old base address not removed after MMAP remap\n")));
394 alloc
[ i
]->remove();
402 alloc
[ i
]->remove();
410 run_main (int, ACE_TCHAR
*[])
412 ACE_START_TEST (ACE_TEXT ("Based_Pointer_Test"));
416 retval
+= singleton_test ();
417 retval
+= mmap_map_test();
418 retval
+= mmap_persistent_map_test();
419 retval
+= mmap_remap_test();
421 ACE_Based_Pointer_Basic
<Foo
> Foo_Ptr
;
422 ACE_UNUSED_ARG (Foo_Ptr
);
425 return retval
== 0 ? 0 : 1;
428 #else /* ! ACE_HAS_POSITION_INDEPENDENT_POINTERS */
431 run_main (int, ACE_TCHAR
*[])
433 ACE_START_TEST (ACE_TEXT ("Based_Pointer_Test"));
434 ACE_Based_Pointer_Basic
<Foo
> Foo_Ptr
;
435 ACE_UNUSED_ARG (Foo_Ptr
);
439 #endif /* ACE_HAS_POSITION_INDEPENDENT_POINTERS */