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 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 #if defined (ACE_OPENVMS)
112 // with OPENVMS symbol names > 31 cause us trouble with dlsym()
113 void* foo
= dll
.symbol (ACE_TEXT ("get_based_pointer_repo_inst"));
115 void* foo
= dll
.symbol (ACE_TEXT ("get_based_pointer_repository_instance"));
118 // Cast the void* to function* with a long as intermediate.
119 ptrdiff_t tmp
= reinterpret_cast<ptrdiff_t> (foo
);
120 Get_Bp_Repository_Inst get_bp_repository_inst
=
121 reinterpret_cast<Get_Bp_Repository_Inst
> (tmp
);
122 if (get_bp_repository_inst
== 0)
123 ACE_ERROR_RETURN ((LM_ERROR
,
128 void* baddr_dll
= get_bp_repository_inst ();
132 if (baddr_dll
!= baddr1
)
134 ACE_ERROR_RETURN ((LM_ERROR
,
135 ACE_TEXT ("ACE_Based_Pointer_Repository is not a ")
136 ACE_TEXT ("singleton in DLL <%@> <%@>\n"),
141 #endif /* ACE_HAS_DYNAMIC_LINKING */
146 // Check that MMAP memory blocks are correctly mapped
147 // into the Based_Pointer_Repository
151 MMAP_Allocator
* alloc
= 0;
153 ACE_OS::unlink("foo");
155 // The 'options' are only here to quiet MSVC 6. It can be removed
156 // when MSVC 6 support is removed.
157 MMAP_Allocator::MEMORY_POOL_OPTIONS
*options
= 0;
160 MMAP_Allocator (ACE_TEXT ("foo"), ACE_TEXT ("foo"), options
),
163 void* addr
= alloc
->base_addr();
167 ACE_TEXT ("Unable to get base to MMAP Memory Pool\n")));
173 // Check a base address mapping was added to the Repository
174 // when the pool was created
176 if(ACE_BASED_POINTER_REPOSITORY::instance()->find(addr
, ba
) == -1)
178 ACE_ERROR((LM_ERROR
, ACE_TEXT ("Unable to access repository\n")));
189 ACE_ERROR_RETURN ((LM_ERROR
,
190 ACE_TEXT ("MMAP pool mapping not present\n")),
194 // Check Mapping is removed when object is deleted
195 if (ACE_BASED_POINTER_REPOSITORY::instance()->find(addr
, ba
) == -1)
197 ACE_ERROR_RETURN ((LM_ERROR
,
198 ACE_TEXT ("Unable to access repository\n")),
203 ACE_ERROR_RETURN ((LM_ERROR
,
204 ACE_TEXT ("MMAP pool mapping not removed\n")),
211 // Check that persistent MMAP memory blocks are correctly remapped
212 // into the Based_Pointer_Repository
213 // (i.e. maps based on backing stores that are already
214 // present in the filesystem)
215 // (see http://bugzilla.dre.vanderbilt.edu/show_bug.cgi?id=2216)
217 mmap_persistent_map_test()
219 MMAP_Allocator
* alloc
= 0;
221 // The 'options' are only here to quiet MSVC 6. It can be removed
222 // when MSVC 6 support is removed.
223 MMAP_Allocator::MEMORY_POOL_OPTIONS
*options
= 0;
224 ACE_OS::unlink("foo");
228 MMAP_Allocator (ACE_TEXT ("foo"), ACE_TEXT ("foo"), options
),
232 // Delete Malloc and the memory pool, but do not remove
234 alloc
->memory_pool().release(0);
238 // Recreate segment with existing backing store
242 MMAP_Allocator (ACE_TEXT ("foo"), ACE_TEXT("foo"), options
),
245 void* addr
= alloc
->base_addr();
248 ACE_ERROR ((LM_ERROR
,
249 ACE_TEXT ("Unable to get base to persistent MMAP Memory Pool\n")));
255 if(ACE_BASED_POINTER_REPOSITORY::instance()->find(addr
, ba
) == -1)
257 ACE_ERROR ((LM_ERROR
,
258 ACE_TEXT ("Unable to find base address after map of persistent segment\n")));
265 ACE_ERROR ((LM_ERROR
,
266 ACE_TEXT ("Persistent MMAP Memory Pool not mapped\n")));
277 // Check that MMAP memory blocks are correctly remapped
278 // into the Based_Pointer_Repository
279 // (i.e. when a segment is resized it may move its base address
280 // because the OS cannot fit the new segment size at the same
281 // base address, in this case the Repository must be updated)
282 // (see http://bugzilla.dre.vanderbilt.edu/show_bug.cgi?id=2218)
286 // Use a Position Independent memory segment
287 // because this one is going to move
289 MMAP_Allocator
*alloc
[ 3 ]= {0, 0, 0};
290 void *pool_base
[ 3 ]= {0, 0, 0};
292 // Make sure the Pool options are set to allow
293 // the segment to move
294 ACE_MMAP_Memory_Pool_Options
data_opts(
296 ACE_MMAP_Memory_Pool_Options::NEVER_FIXED
);
301 ACE_TCHAR store
[ MAXPATHLEN
+ 1 ];
302 ACE_OS::snprintf( store
, MAXPATHLEN
+ 1, ACE_TEXT("foo%d"), i
);
303 ACE_OS::unlink( store
);
305 ACE_NEW_RETURN (alloc
[ i
],
306 MMAP_Allocator (store
, store
, &data_opts
),
308 pool_base
[ i
]= alloc
[ i
]->base_addr();
311 // sort pools into base address order
314 if (pool_base
[ i
] < pool_base
[ i
+1 ])
316 void *tmp1
= pool_base
[ i
];
317 MMAP_Allocator
*tmp2
= alloc
[ i
];
318 pool_base
[ i
]= pool_base
[ i
+1 ];
319 alloc
[ i
]= alloc
[ i
+1 ];
320 pool_base
[ i
+1 ]= tmp1
;
326 // alloc[1] is now bounded, whether memory grows up or
327 // down, it will hit either alloc[0] or alloc[2] and have
330 // Calculate maximum space between base addresses
332 size_t size
= (char *) pool_base
[ 0 ] - (char *) pool_base
[ 1 ];
333 size_t tmpsize
= (char *) pool_base
[ 1 ] - (char *) pool_base
[ 2 ];
334 size
= (size
< tmpsize
) ? tmpsize
: size
;
336 // force pool to move
339 (void)alloc
[ 1 ]->malloc(size
);
340 void *nba
= alloc
[ 1 ]->base_addr();
342 if (pool_base
[ 1 ] == nba
)
344 ACE_ERROR ((LM_ERROR
,
345 ACE_TEXT ("MMAP Pool did not move base address as expected\n")));
348 alloc
[ i
]->remove();
355 if (ACE_BASED_POINTER_REPOSITORY::instance()->find(nba
, ba
) == -1)
357 ACE_ERROR ((LM_ERROR
,
358 ACE_TEXT ("Unable to find base address after remap of segment\n")));
361 alloc
[ i
]->remove();
369 ACE_ERROR ((LM_ERROR
,
370 ACE_TEXT ("New base address not mapped after MMAP remap\n")));
373 alloc
[ i
]->remove();
379 // Check old base address has been removed
380 // from the repository
381 if (ACE_BASED_POINTER_REPOSITORY::instance()->find( pool_base
[ 1 ], ba
) == -1)
383 ACE_ERROR ((LM_ERROR
,
384 ACE_TEXT ("Unable to find base address after remap of segment\n")));
387 alloc
[ i
]->remove();
393 if (ba
== pool_base
[ 1 ])
395 ACE_ERROR ((LM_ERROR
,
396 ACE_TEXT ("Old base address not removed after MMAP remap\n")));
399 alloc
[ i
]->remove();
407 alloc
[ i
]->remove();
415 run_main (int, ACE_TCHAR
*[])
417 ACE_START_TEST (ACE_TEXT ("Based_Pointer_Test"));
421 retval
+= singleton_test ();
422 retval
+= mmap_map_test();
423 retval
+= mmap_persistent_map_test();
424 retval
+= mmap_remap_test();
426 ACE_Based_Pointer_Basic
<Foo
> Foo_Ptr
;
427 ACE_UNUSED_ARG (Foo_Ptr
);
430 return retval
== 0 ? 0 : 1;
433 #else /* ! ACE_HAS_POSITION_INDEPENDENT_POINTERS */
436 run_main (int, ACE_TCHAR
*[])
438 ACE_START_TEST (ACE_TEXT ("Based_Pointer_Test"));
439 ACE_Based_Pointer_Basic
<Foo
> Foo_Ptr
;
440 ACE_UNUSED_ARG (Foo_Ptr
);
444 #endif /* ACE_HAS_POSITION_INDEPENDENT_POINTERS */