New Interprocess version

[SVN r38272]
This commit is contained in:
Ion Gaztañaga
2007-07-22 14:16:59 +00:00
parent 2c2657a933
commit d30380e07d
50 changed files with 2702 additions and 1318 deletions

View File

@@ -7,12 +7,10 @@
#
# See http://www.boost.org for updates, documentation, and revision history.
project boost/interprocess/doc ;
import doxygen ;
import quickbook ;
import boostbook : boostbook ;
using quickbook ;
doxygen interprocess_doxygen
doxygen autodoc
:
[ glob ../../../boost/interprocess/*.hpp ]
[ glob ../../../boost/interprocess/allocators/*.hpp ]
@@ -28,21 +26,17 @@ doxygen interprocess_doxygen
<doxygen:param>HIDE_UNDOC_MEMBERS=YES
<doxygen:param>EXTRACT_PRIVATE=NO
<doxygen:param>EXPAND_ONLY_PREDEF=YES
# <doxygen:param>ENABLE_PREPROCESSING=NO
# <doxygen:param>MACRO_EXPANSION=YES
# <doxygen:param>SEARCH_INCLUDES=YES
# <doxygen:param>INCLUDE_PATH=$(BOOST_ROOT)
;
xml interprocess_xml : interprocess.qbk ;
xml interprocess : interprocess.qbk ;
boostbook interprocess
boostbook standalone
:
interprocess_xml
interprocess_doxygen
interprocess
:
<xsl:param>boost.root=../../../..
<xsl:param>boost.libraries=../../../../libs/libraries.htm
<xsl:param>generate.section.toc.level=3
<xsl:param>chunk.first.sections=1
<dependency>autodoc
;

View File

@@ -1,8 +1,16 @@
[/
/ Copyright (c) 2007 Ion Gaztanaga
/
/ Distributed under the Boost Software License, Version 1.0. (See accompanying
/ file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
/]
[library Boost.Interprocess
[quickbook 1.4]
[version 2007-06-23]
[quickbook 1.3]
[authors [Gazta&ntilde;aga, Ion]]
[copyright 2005- 2007 Ion Gazta&ntilde;aga]
[id interprocess]
[dirname interprocess]
[purpose Interprocess communication utilities]
[license
Distributed under the Boost Software License, Version 1.0.
@@ -50,14 +58,15 @@ compiler include path.
[*Boost.Interprocess] has been tested in the following compilers/platforms:
* Visual 7.1/WinXP
* Visual 8.0/WinXP
* GCC 4.1.1/MinGW
* GCC 3.4.4/Cygwin
* Intel 9.1/WinXP
* GCC 4.1.2/Linux
* Codewarrior 9.4/WinXP
* Visual 7.1 Windows XP
* Visual 8.0 Windows XP
* GCC 4.1.1 MinGW
* GCC 3.4.4 Cygwin
* Intel 9.1 Windows XP
* GCC 4.1.2 Linux
* Codewarrior 9.4 Windows XP
* GCC 3.4.3 Solaris 11
* GCC 4.0 MacOs 10.4.1
[endsect]
@@ -482,7 +491,7 @@ This is the server process:
[doc_windows_shared_memory]
Now, before destroying the
[classref boost::interprocess::windows_shared memory windows_shared memory]
[classref boost::interprocess::windows_shared_memory windows_shared memory]
object, launch the client process:
[import ../example/doc_windows_shared_memory2.cpp]
@@ -785,18 +794,18 @@ mapped regions for a file with which has `2*page_size` bytes:
//Map the first quarter of the file
//This will use a whole page
mapped_region region1( shm //Map shared memory
, read_write //Map it as read-write
, 0 //Map from offset 0
, page_size/2 //Map page_size/2 bytes
mapped_region region1( shm //Map shared memory
, read_write //Map it as read-write
, 0 //Map from offset 0
, page_size/2 //Map page_size/2 bytes
);
//Map the rest of the file
//This will use a 2 pages
mapped_region region2( shm //Map shared memory
, read_write //Map it as read-write
, page_size/2 //Map from offset 0
, 3*page_size/2 //Map page_size/2 bytes
mapped_region region2( shm //Map shared memory
, read_write //Map it as read-write
, page_size/2 //Map from offset 0
, 3*page_size/2 //Map the rest of the shared memory
);
In this example, a half of the page is wasted in the first mapping and another
@@ -804,17 +813,17 @@ half is wasted in the second because the offset is not a multiple of the
page size. The mapping with the minimum resource usage would be to map whole pages:
//Map the whole first half: uses 1 page
mapped_region region1( shm //Map shared memory
, read_write //Map it as read-write
, 0 //Map from offset 0
, page_size //Map page_size/2 bytes
mapped_region region1( shm //Map shared memory
, read_write //Map it as read-write
, 0 //Map from offset 0
, page_size //Map a full page_size
);
//Map the second half: uses 1 page
mapped_region region2( shm //Map shared memory
, read_write //Map it as read-write
, page_size //Map from offset 0
, page_size //Map page_size/2 bytes
mapped_region region2( shm //Map shared memory
, read_write //Map it as read-write
, page_size //Map from offset 0
, page_size //Map the rest
);
How can we obtain the [*page size]? The `mapped_region` class has an static
@@ -825,13 +834,6 @@ function that returns that value:
//Obtain the page size of the system
std::size_t page_size = mapped_region::get_page_size();
//This mapping will optimally use system resources
mapped_region region ( shm //Map shared memory
, read_write //Map it as read-write
, 0 //Map from offset 0
, page_size //Map whole page
);
The operating system might also limit the number of mapped memory regions per
process or per system.
@@ -2226,7 +2228,7 @@ queue using 3 methods:
A message queue [*just copies raw bytes between processes] and does not send
objects. This means that if we want to send an object using a message queue
[*the object must be binary serializable]. For example, we can send integers
between processes but [*not] a std::string. You should use [*Boost.Serialization]
between processes but [*not] a `std::string`. You should use [*Boost.Serialization]
or use advanced [*Boost.Interprocess] mechanisms to send complex data between
processes.
@@ -2756,8 +2758,7 @@ a memory management algorithm to allocate portions of that segment.
Many times, we also want to associate a names to objects created in shared memory, so
all the processes can find the object using the name.
Managed memory segments offer a lot of possibilities and [*Boost.Interprocess] offers
4 managed memory segment classes:
[*Boost.Interprocess] offers 4 managed memory segment classes:
* To manage a shared memory mapped region ([*basic_managed_shared_memory] class).
* To manage a memory mapped file ([*basic_managed_mapped_file]).
@@ -2824,7 +2825,7 @@ These classes can be customized with the following template parameters:
addresses in each process. If `void_pointer` is `void*` only fixed
address mapping could be used.
* See [link boost_interprocess.customizing_boost_interprocess.custom_interprocess_alloc Writing a new memory
* See [link interprocess.customizing_interprocess.custom_interprocess_alloc Writing a new memory
allocation algorithm] for more details about memory algorithms.
* *IndexType* is the type of index that will be used to store the name-object
@@ -3160,36 +3161,6 @@ if there is no more memory and the non-throwing version returns 0 pointer.
[endsect]
[section:allocate_aligned Allocating aligned fragments of a managed memory segment]
Sometimes it's interesting to be able to allocate aligned fragments of memory
from a segment and managed memory segments offer also that possibility.
This allocation is similar to the previously shown raw memory allocation but
it takes an additional parameter specifying the alignment. There is
a restriction for the alignment: [*the alignment must be power of two].
If a user wants to allocate many aligned blocks (for example aligned to 128 bytes),
the size that minimizes the memory waste is a value that's is nearly a multiple
of that alignment (for example 128 - some bytes). This way, if the first bytes
of a big block of memory are used
to fulfill the aligned allocation, the rest of the block is also aligned to that
value and ready for the next aligned allocation. Note
that [*a size equal to the alignment is not correct] because the memory
allocation algorithm needs some payload bytes to store deallocation information.
If the user could know the size of the payload, he could request a size that will
be optimal to allocate aligned chunks of memory maximizing both the size of the
request [*and] the possibilities of future aligned allocations. This information
is stored in the PayloadPerAllocation constant of managed memory segments.
Here's is an small example showing how aligned allocation is used:
[import ../example/doc_managed_aligned_allocation.cpp]
[doc_managed_aligned_allocation]
[endsect]
[section:segment_offset Obtaining handles to identify data]
The class also offers conversions between absolute addresses that belong to
@@ -3336,10 +3307,16 @@ using this "unique instance" mechanism.
[section:synchronization Synchronization guarantees]
One of the features of named/anonymous/unique allocations/searches/destructions is that
they are [*atomic]. Named allocations use the synchronization scheme defined by the
internal `mutex_family` typedef defined by the template parameter MemoryAlgorithm of
the managed memory segment. So that two processes can call:
One of the features of named/unique allocations/searches/destructions is that
they are [*atomic]. Named allocations use the recursive synchronization scheme defined by the
internal `mutex_family` typedef defined of the memory allocation algorithm template
parameter (`MemoryAlgorithm`). That is, the mutex type used to synchronize
named/unique allocations is defined by the
`MemoryAlgorithm::mutex_family::recursive_mutex_type` type. For shared memory,
and memory mapped file based managed segments this recursive mutex is defined
as [classref boost::interprocess::interprocess_recursive_mutex].
If two processes can call:
[c++]
@@ -3412,7 +3389,7 @@ just must specify [boost::interprocess::map_index map_index] as a template param
[*Boost.Interprocess] plans to offer an *unordered_map* based index as soon as this
container is included in Boost. If these indexes are not enough for you, you can define
your own index type. To know how to do this, go to
[link boost_interprocess.customizing_boost_interprocess.custom_indexes Building custom indexes] section.
[link interprocess.customizing_interprocess.custom_indexes Building custom indexes] section.
[endsect]
@@ -3441,9 +3418,35 @@ memory segment using `get_segment_manager` member:
[endsect]
[section:managed_memory_segment_additional_features Additional functions]
[section:managed_memory_segment_information Obtaining information about a constructed object]
Managed memory segments offer additional functions:
Once an object is constructed using `construct<>` function family, the
programmer can obtain information about the object using a pointer to the
object. The programmer can obtain the following information:
* Name of the object: If it's a named instance, the name used in the construction
function is returned, otherwise 0 is returned.
* Length of the object: Returns the number of elements of the object (1 if it's
a single value, >=1 if it's an array).
* The type of construction: Whether the object was construct using a named,
unique or anonymous construction.
Here is an example showing this functionality:
[import ../example/doc_managed_construction_info.cpp]
[doc_managed_construction_info]
[endsect]
[endsect]
[section:managed_memory_segment_advanced_features Managed Memory Segment Advanced Features]
[section:managed_memory_segment_information Obtaining information about the managed segment]
These functions are available to obtain information about the managed memory segments:
Obtain the size of the memory segment:
@@ -3463,22 +3466,42 @@ Clear to zero the free memory:
managed_shm.zero_free_memory();
Returns true if all memory has been deallocated, false otherwise:
Know if all memory has been deallocated, false otherwise:
[c++]
managed_shm.all_memory_deallocated();
Tests internal structures of the managed segment and returns true
Test internal structures of the managed segment. Returns true
if no errors are detected:
[c++]
managed_shm.check_sanity();
Reserves memory to make the subsequent allocation of named or unique objects more
efficient. This function is only useful for pseudo-intrusive or non-node indexes (like
`flat_map_index`, `iunordered_set_index`). This function has no effect with the
Obtain the number of named and unique objects allocated in the segment:
[c++]
managed_shm.get_num_named_objects();
managed_shm.get_num_unique_objects();
[endsect]
[section:managed_memory_segment_advanced_index_functions Advanced index functions]
As mentioned, the managed segment stores the information about named and unique
objects in two indexes. Depending on the type of those indexes, the index must
reallocate some auxiliary structures when new named or unique allocations are made.
For some indexes, if the user knows how many maned or unique objects is going to
create it's possible to preallocate some structures to obtain much better
performance (if the index is an ordered vector it can preallocate memory to avoid
reallocations, if the index is a hash structure it can preallocate the bucket array...).
The following functions reserve memory to make the subsequent allocation of
named or unique objects more efficient. These functions are only useful for
pseudo-intrusive or non-node indexes (like `flat_map_index`,
`iunordered_set_index`). These functions has no effect with the
default index (`iset_index`) or other indexes (`map_index`):
[c++]
@@ -3486,19 +3509,22 @@ default index (`iset_index`) or other indexes (`map_index`):
managed_shm.reserve_named_objects(1000);
managed_shm.reserve_unique_objects(1000);
Returns the number of named and unique objects allocated in the segment:
[c++]
managed_shm.get_num_named_objects();
managed_shm.get_num_unique_objects();
managed_shm.reserve_named_objects(1000);
managed_shm.reserve_unique_objects(1000);
Returns constant iterators to the range of named and unique objects stored in the
managed segment. [*Caution:] These functions are for debugging purposes
and they are [*not] thread-safe. If any other process creates or destroys
named/unique objects while a process iterates the named/unique objects the
results are undefined. Iterators are invalidated after each named/unique object
creation/erasure:
Managed memory segments also offer the possibility to iterate through
constructed named and unique objects for debugging purposes. [*Caution: this
iteration is not thread-safe] so the user should make sure that no other
thread is manipulating named or unique indexes (creating, erasing,
reserving...) in the segment. Other operations not involving indexes can
be concurrently executed (raw memory allocation/deallocations, for example).
The following functions return constant iterators to the range of named and
unique objects stored in the managed segment. Depending on the index type,
iterators might be invalidated after a named or unique
creation/erasure/reserve operation:
[c++]
@@ -3530,6 +3556,282 @@ creation/erasure:
[endsect]
[section:allocate_aligned Allocating aligned memory portions]
Sometimes it's interesting to be able to allocate aligned fragments of memory
because of some hardware or software restrictions. Sometimes, having
aligned memory is an feature that can be used to improve several
memory algorithms.
This allocation is similar to the previously shown raw memory allocation but
it takes an additional parameter specifying the alignment. There is
a restriction for the alignment: [*the alignment must be power of two].
If a user wants to allocate many aligned blocks (for example aligned to 128 bytes),
the size that minimizes the memory waste is a value that's is nearly a multiple
of that alignment (for example 2*128 - some bytes). The reason for this is that
every memory allocation usually needs some additional metadata in the first
bytes of the allocated buffer. If the user can know the value of "some bytes"
and if the first bytes of a free block of memory are used to fulfill the aligned
allocation, the rest of the block can be left also aligned and ready for the next
aligned allocation. Note that requesting [*a size multiple of the alignment is not optimal]
because lefts the next block of memory unaligned due to the needed metadata.
Once the programmer knows the size of the payload of every memory allocation,
he can request a size that will be optimal to allocate aligned chunks
of memory maximizing both the size of the
request [*and] the possibilities of future aligned allocations. This information
is stored in the PayloadPerAllocation constant of managed memory segments.
Here's is an small example showing how aligned allocation is used:
[import ../example/doc_managed_aligned_allocation.cpp]
[doc_managed_aligned_allocation]
[endsect]
[/
/
/[section:managed_memory_segment_multiple_allocations Multiple allocation functions]
/
/If an application needs to allocate a lot of memory buffers but it needs
/to deallocate them independently, the application is normally forced to loop
/calling `allocate()`. Managed memory segments offer an alternative function
/to pack several allocations in a single call obtaining memory buffers that:
/
/* are packed contiguously in memory (which improves locality)
/* can be independently deallocated.
/
/This allocation method is much faster
/than calling `allocate()` in a loop. The downside is that the segment
/must provide a contiguous memory segment big enough to hold all the allocations.
/Managed memory segments offer this functionality through `allocate_many()` functions.
/There are 2 types of `allocate_many` functions:
/
/* Allocation of N buffers of memory with the same size.
/* Allocation ot N buffers of memory, each one of different size.
/
/[c++]
/
/ //!Allocates n_elements of elem_size bytes.
/ multiallocation_iterator allocate_many(std::size_t elem_size, std::size_t min_elements, std::size_t preferred_elements, std::size_t &received_elements);
/
/ //!Allocates n_elements, each one of elem_sizes[i] bytes.
/ multiallocation_iterator allocate_many(const std::size_t *elem_sizes, std::size_t n_elements);
/
/ //!Allocates n_elements of elem_size bytes. No throwing version.
/ multiallocation_iterator allocate_many(std::size_t elem_size, std::size_t min_elements, std::size_t preferred_elements, std::size_t &received_elements, std::nothrow_t nothrow);
/
/ //!Allocates n_elements, each one of elem_sizes[i] bytes. No throwing version.
/ multiallocation_iterator allocate_many(const std::size_t *elem_sizes, std::size_t n_elements, std::nothrow_t nothrow);
/
/All functions return a `multiallocation iterator` that can be used to obtain
/pointers to memory the user can overwrite. A `multiallocation_iterator`:
/
/* Becomes invalidated if the memory is pointing to is deallocated or
/ the next iterators (which previously were reachable with `operator++`)
/ become invalid.
/* Returned from `allocate_many` can be checked in a boolean expression to
/ know if the allocation has been successful.
/* A default constructed `multiallocation iterator` indicates
/ both an invalid iterator and the "end" iterator.
/* Dereferencing an iterator (`operator *()`) returns a `char*` value
/ pointing to the first byte of memory that the user can overwrite
/ in that memory buffer.
/* The iterator category depends on the memory allocation algorithm,
/ but it's a least a forward iterator.
/
/Here's an small example showing all this functionality:
/
/[import ../example/doc_managed_multiple_allocation.cpp]
/[doc_managed_multiple_allocation]
/
/Allocating N buffers of the same size improves the performance of pools
/and node containers (for example STL-like lists):
/when inserting a range of forward iterators in a STL-like
/list, the insertion function can detect the number of needed elements
/and allocate in a single call. The nodes still can be deallocated.
/
/Allocating N buffers of different sizes can be used to speed up allocation in
/cases where several objects must always be allocated at the same time but
/deallocated at different times. For example, a class might perform several initial
/allocations (some header data for a network packet, for example) in its
/constructor but also allocations of buffers that might be reallocated in the future
/(the data to be sent through the network). Instead of allocating all the data
/independently, the constructor might use `allocate_many()` to speed up the
/initialization, but it still can deallocate and expand the memory of the variable
/size element.
/
/In general, `allocate_many` is useful with large values of N. Overuse
/of `allocate_many` can increase the effective memory usage,
/because it can't reuse existing non-contiguous memory fragments that
/might be available for some of the elements.
/
/[endsect]
]
[section:managed_memory_segment_expand_in_place Expand in place memory allocation]
When programming some data structures such as vectors, memory reallocation becomes
an important tool to improve performance. Managed memory segments offer an advanced
reallocation function that offers:
* Forward expansion: An allocated buffer can be expanded so that the end of the buffer
is moved further. New data can be written between the old end and the new end.
* Backwards expansion: An allocated buffer can be expanded so that the beginning of
the buffer is moved backwards. New data can be written between the new beginning
and the old beginning.
* Shrinking: An allocated buffer can be shrunk so that the end of the buffer
is moved backwards. The memory between the new end and the old end can be reused
for future allocations.
The expansion can be combined with the allocation of a new buffer if the expansion
fails obtaining a function with "expand, if fails allocate a new buffer" semantics.
Apart from this features, the function always returns the real size of the
allocated buffer, because many times, due to alignment issues the allocated
buffer a bit bigger than the requested size. Thus, the programmer can maximize
the memory use using `allocation_command`.
Here's the declaration of the function:
[c++]
enum allocation_type
{
//Bitwise OR (|) combinable values
allocate_new = ...,
expand_fwd = ...,
expand_bwd = ...,
shrink_in_place = ...,
nothrow_allocation = ...
};
template<class T>
std::pair<T *, bool>
allocation_command( allocation_type command
, std::size_t limit_size
, std::size_t preferred_size
, std::size_t &received_size
, T *reuse_ptr = 0);
[*Preconditions for the function]:
* If the parameter command contains the value `shrink_in_place` it can't
contain any of these values: `expand_fwd`, `expand_bwd`.
* If the parameter command contains `expand_fwd` or `expand_bwd`, the parameter
`reuse_ptr` must be non-null and returned by a previous allocation function.
* If the parameter command contains the value `shrink_in_place`, the parameter
`limit_size` must be equal or greater than the parameter `preferred_size`.
* If the parameter `command` contains any of these values: `expand_fwd` or `expand_bwd`,
the parameter `limit_size` must be equal or less than the parameter `preferred_size`.
[*Which are the effects of this function:]
* If the parameter command contains the value `shrink_in_place`, the function
will try to reduce the size of the memory block referenced by pointer `reuse_ptr`
to the value `preferred_size` moving only the end of the block.
If it's not possible, it will try to reduce the size of the memory block as
much as possible as long as this results in `size(p) <= limit_size`. Success
is reported only if this results in `preferred_size <= size(p)` and `size(p) <= limit_size`.
* If the parameter `command` only contains the value `expand_fwd` (with optional
additional `nothrow_allocation`), the allocator will try to increase the size of the
memory block referenced by pointer reuse moving only the end of the block to the
value `preferred_size`. If it's not possible, it will try to increase the size
of the memory block as much as possible as long as this results in
`size(p) >= limit_size`. Success is reported only if this results in `limit_size <= size(p)`.
* If the parameter `command` only contains the value `expand_bwd` (with optional
additional `nothrow_allocation`), the allocator will try to increase the size of
the memory block referenced by pointer `reuse_ptr` only moving the start of the
block to a returned new position new_ptr. If it's not possible, it will try to
move the start of the block as much as possible as long as this results in
`size(new_ptr) >= limit_size`. Success is reported only if this results in
`limit_size <= size(new_ptr)`.
* If the parameter `command` only contains the value `allocate_new` (with optional
additional `nothrow_allocation`), the allocator will try to allocate memory for
`preferred_size` objects. If it's not possible it will try to allocate memory for
at least limit_size` objects.
* If the parameter `command` only contains a combination of `expand_fwd` and
`allocate_new`, (with optional additional `nothrow_allocation`) the allocator will
try first the forward expansion. If this fails, it would try a new allocation.
* If the parameter `command` only contains a combination of `expand_bwd` and
`allocate_new` (with optional additional `nothrow_allocation`), the allocator will
try first to obtain `preferred_size` objects using both methods if necessary.
If this fails, it will try to obtain `limit_size` objects using both methods if
necessary.
* If the parameter `command` only contains a combination of `expand_fwd` and
`expand_bwd` (with optional additional `nothrow_allocation`), the allocator will
try first forward expansion. If this fails it will try to obtain preferred_size
objects using backwards expansion or a combination of forward and backwards expansion.
If this fails, it will try to obtain `limit_size` objects using both methods if
necessary.
* If the parameter `command` only contains a combination of allocation_new,
`expand_fwd` and `expand_bwd`, (with optional additional `nothrow_allocation`)
the allocator will try first forward expansion. If this fails it will try to obtain
preferred_size objects using new allocation, backwards expansion or a combination of
forward and backwards expansion. If this fails, it will try to obtain `limit_size`
objects using the same methods.
* The allocator always writes the size or the expanded/allocated/shrunk memory block
in `received_size`. On failure the allocator writes in `received_size` a possibly
successful `limit_size` parameter for a new call.
[*Throws an exception if two conditions are met:]
* The allocator is unable to allocate/expand/shrink the memory or there is an
error in preconditions
* The parameter command does not contain `nothrow_allocation`.
[*This function returns:]
* The address of the allocated memory or the new address of the expanded memory
as the first member of the pair. If the parameter command contains
`nothrow_allocation` the first member will be 0
if the allocation/expansion fails or there is an error in preconditions.
* The second member of the pair will be false if the memory has been allocated,
true if the memory has been expanded. If the first member is 0, the second member
has an undefined value.
[*Notes:]
* If the user chooses `char` as template argument the returned buffer will
be suitably aligned to hold any type.
* If the user chooses `char` as template argument and a backwards expansion is
performed, although properly aligned, the returned buffer might not be
suitable because the distance between the new beginning and the old beginning
might not multiple of the type the user wants to construct, because due to internal
restriction the expansion can be slightly bigger than the requested. [*When
performing backwards expansion, if you have already constructed objects in the
old buffer, make sure to specify correctly the type.]
Here is an small example that shows the use of `allocation_command`:
[import ../example/doc_managed_allocation_command.cpp]
[doc_managed_allocation_command]
`allocation_commmand` is a very powerful function that can lead to important
performance gains. It's specially useful when programming vector-like data
structures where the programmer can minimize both the number of allocation
requests and the memory waste.
[endsect]
[endsect]
[section:allocator_introduction Introduction to Interprocess allocators]
@@ -3695,7 +3997,7 @@ offers 3 allocators based on this segregated storage algorithm:
To know the details of the implementation of
of the segregated storage pools see the
[link boost_interprocess.architecture_2.implementation_segregated_storage_pools Implementation of [*Boost.Interprocess] segregated storage pools]
[link interprocess.architecture_2.implementation_segregated_storage_pools Implementation of [*Boost.Interprocess] segregated storage pools]
section.
[section:segregated_allocators_common Additional parameters and functions of segregated storage node allocators]
@@ -3704,7 +4006,7 @@ section.
[classref boost::interprocess::private_node_allocator private_node_allocator] and
[classref boost::interprocess::cached_node_allocator cached_node_allocator] implement
the standard allocator interface and the functions explained in the
[link boost_interprocess.allocator_introduction.allocator_properties Properties of Boost.Interprocess allocators].
[link interprocess.allocator_introduction.allocator_properties Properties of Boost.Interprocess allocators].
All these allocators are templatized by 3 parameters:
@@ -3731,7 +4033,7 @@ pool is used for each node size. This is not possible if you try to share
a node allocator between processes. To achieve this sharing
[classref boost::interprocess::node_allocator node_allocator]
uses the segment manager's unique type allocation service
(see [link boost_interprocess.managed_memory_segment_features.unique Unique instance construction] section).
(see [link interprocess.managed_memory_segment_features.unique Unique instance construction] section).
In the initialization, a
[classref boost::interprocess::node_allocator node_allocator]
@@ -3926,7 +4228,7 @@ and performance (aceptable for many applications) with the ability to return fre
of nodes to the memory segment, so that they can be used by any other container or managed
object construction. To know the details of the implementation of
of "adaptive pools" see the
[link boost_interprocess.architecture_2.implementation_adaptive_pools Implementation of [*Boost.Intrusive] adaptive pools]
[link interprocess.architecture_2.implementation_adaptive_pools Implementation of [*Boost.Intrusive] adaptive pools]
section.
Like with segregated storage based node allocators, Boost.Interprocess offers
@@ -3940,7 +4242,7 @@ Like with segregated storage based node allocators, Boost.Interprocess offers
[classref boost::interprocess::private_adaptive_pool private_adaptive_pool] and
[classref boost::interprocess::cached_adaptive_pool cached_adaptive_pool] implement
the standard allocator interface and the functions explained in the
[link boost_interprocess.allocator_introduction.allocator_properties Properties of Boost.Interprocess allocators].
[link interprocess.allocator_introduction.allocator_properties Properties of Boost.Interprocess allocators].
All these allocators are templatized by 4 parameters:
@@ -4054,7 +4356,7 @@ An example using [classref boost::interprocess::private_adaptive_pool private_ad
[endsect]
[section:cached_adaptive_pool boost::interprocess::cached_adaptive_pool: Avoiding synchronization overhead]
[section:cached_adaptive_pool cached_adaptive_pool: Avoiding synchronization overhead]
Adaptive pools have also a cached version. In this allocator the allocator caches
some nodes to avoid the synchronization and bookeeping overhead of the shared
@@ -4238,7 +4540,7 @@ in a generic way, [*Boost.Interprocess] offers the following classes:
to be used in managed memory segments like shared memory.
It's implemented using a vector-like contiguous storage, so
it has fast c string conversion and can be used with the
[link boost_interprocess.streams.vectorstream vectorstream] iostream formatting classes.
[link interprocess.streams.vectorstream vectorstream] iostream formatting classes.
To use it include:
[c++]
@@ -4417,7 +4719,7 @@ Let's see an example of the use of managed_external_buffer:
[*Boost.Interprocess] STL compatible allocators can also be used to place STL
compatible containers in the user segment.
[classref boost::interprocess::managed_external_buffer managed_external_buffer] can
[classref boost::interprocess::basic_managed_external_buffer basic_managed_external_buffer] can
be also useful to build small databases for embedded systems limiting the size of
the used memory to a predefined memory chunk, instead of letting the database
fragment the heap memory.
@@ -4474,7 +4776,7 @@ To use a managed heap memory, you must include the following header:
#include <boost/interprocess/managed_heap_memory.hpp>
The use is exactly the same as
[classref boost::interprocess::managed_external_buffer],
[classref boost::interprocess::basic_managed_external_buffer],
except that memory is created by
the managed memory segment itself using dynamic (new/delete) memory.
@@ -4688,17 +4990,17 @@ setting the string from which the stream will extract data. An example:
The problem is even worse if the string is a shared-memory string, because
to extract data, we must copy the data first from shared-memory to a
std::string and then to a stringstream. To encode data in a shared-memory
string we should copy data from a stringstream to a std::string and then
`std::string` and then to a `std::stringstream`. To encode data in a shared memory
string we should copy data from a `std::stringstream` to a `std::string` and then
to the shared-memory string.
Because of this overhead, [*Boost.Interprocess] offers a way to format memory-strings
(in shared memory, memory mapped files or any other memory segment) that
can avoid all unneeded string copy and memory allocation/deallocation, while
can avoid all unneeded string copy and memory allocation/deallocations, while
using all iostream facilities. [*Boost.Interprocess] *vectorstream* and *bufferstream* implement
vector-based and fixed-size buffer based storage support for iostreams and
all the formatting/locale hard work is done by standard std::basic_streambuf<>
and std::basic_iostream<> classes.
all the formatting/locale hard work is done by standard `std::basic_streambuf<>`
and `std::basic_iostream<>` classes.
[section:vectorstream Formatting directly in your character vector: vectorstream]
@@ -4709,10 +5011,10 @@ a shared-memory vector is used, data is extracted/written from/to the shared-mem
vector, without additional copy/allocation. We can see the declaration of
basic_vectorstream here:
/*!A basic_iostream class that holds a character vector specified by CharVector
template parameter as its formatting buffer. The vector must have
contiguous storage, like std::vector, boost::interprocess::vector or
boost::interprocess::basic_string*/
//!A basic_iostream class that holds a character vector specified by CharVector
//!template parameter as its formatting buffer. The vector must have
//!contiguous storage, like std::vector, boost::interprocess::vector or
//!boost::interprocess::basic_string
template <class CharVector, class CharTraits =
std::char_traits<typename CharVector::value_type> >
class basic_vectorstream
@@ -4728,37 +5030,37 @@ basic_vectorstream here:
typedef typename std::basic_ios<char_type, CharTraits>::off_type off_type;
typedef typename std::basic_ios<char_type, CharTraits>::traits_type traits_type;
/*!Constructor. Throws if vector_type default constructor throws.*/
//!Constructor. Throws if vector_type default constructor throws.
basic_vectorstream(std::ios_base::openmode mode
= std::ios_base::in | std::ios_base::out);
/*!Constructor. Throws if vector_type(const Parameter &param) throws.*/
//!Constructor. Throws if vector_type(const Parameter &param) throws.
template<class Parameter>
basic_vectorstream(const Parameter &param, std::ios_base::openmode mode
= std::ios_base::in | std::ios_base::out);
~basic_vectorstream(){}
//Returns the address of the stored stream buffer.
//!Returns the address of the stored stream buffer.
basic_vectorbuf<CharVector, CharTraits>* rdbuf() const;
/*!Swaps the underlying vector with the passed vector.
This function resets the position in the stream.
Does not throw.*/
//!Swaps the underlying vector with the passed vector.
//!This function resets the position in the stream.
//!Does not throw.
void swap_vector(vector_type &vect);
/*!Returns a const reference to the internal vector.
Does not throw.*/
//!Returns a const reference to the internal vector.
//!Does not throw.
const vector_type &vector() const;
/*!Preallocates memory from the internal vector.
Resets the stream to the first position.
Throws if the internals vector's memory allocation throws.*/
//!Preallocates memory from the internal vector.
//!Resets the stream to the first position.
//!Throws if the internals vector's memory allocation throws.
void reserve(typename vector_type::size_type size);
};
The vector type is templatized, so that we can use any type of vector:
[*std::vector], [classref boost::interprocess::vector].... But the storage must be *contiguous*,
[*std::vector], [classref boost::interprocess::vector]... But the storage must be *contiguous*,
we can't use a deque. We can even use *boost::interprocess::basic_string*, since it has a
vector interface and it has contiguous storage. *We can't use std::string*, because
although some std::string implementation are vector-based, others can have
@@ -4788,8 +5090,8 @@ embedded systems) choose sprintf family. The *bufferstream* classes offer
iostream interface with direct formatting in a fixed size memory buffer with
protection against buffer overflows. This is the interface:
/*!A basic_iostream class that uses a fixed size character buffer
as its formatting buffer.*/
//!A basic_iostream class that uses a fixed size character buffer
//!as its formatting buffer.
template <class CharT, class CharTraits = std::char_traits<CharT> >
class basic_bufferstream
: public std::basic_iostream<CharT, CharTraits>
@@ -4803,24 +5105,24 @@ protection against buffer overflows. This is the interface:
typedef typename std::basic_ios<char_type, CharTraits>::off_type off_type;
typedef typename std::basic_ios<char_type, CharTraits>::traits_type traits_type;
/*!Constructor. Does not throw.*/
//!Constructor. Does not throw.
basic_bufferstream(std::ios_base::openmode mode
= std::ios_base::in | std::ios_base::out);
/*!Constructor. Assigns formatting buffer. Does not throw.*/
//!Constructor. Assigns formatting buffer. Does not throw.
basic_bufferstream(CharT *buffer, std::size_t length,
std::ios_base::openmode mode
= std::ios_base::in | std::ios_base::out);
/*!Returns the address of the stored stream buffer.*/
//!Returns the address of the stored stream buffer.
basic_bufferbuf<CharT, CharTraits>* rdbuf() const;
/*!Returns the pointer and size of the internal buffer.
Does not throw.*/
//!Returns the pointer and size of the internal buffer.
//!Does not throw.
std::pair<CharT *, std::size_t> buffer() const;
/*!Sets the underlying buffer to a new value. Resets
stream position. Does not throw.*/
//!Sets the underlying buffer to a new value. Resets
//!stream position. Does not throw.
void buffer(CharT *buffer, std::size_t length);
};
@@ -5139,7 +5441,7 @@ pointer. If the [*memory algorithm] will be used just with fixed address mapping
`void_pointer` can be defined as `void*`.
The rest of the interface of a [*Boost.Interprocess] [*memory algorithm] is described in
[link boost_interprocess.customizing_boost_interprocess.custom_interprocess_alloc Writing a new shared memory allocation algorithm]
[link interprocess.customizing_interprocess.custom_interprocess_alloc Writing a new shared memory allocation algorithm]
section. As memory algorithm examples, you can see the implementations
[classref boost::interprocess::simple_seq_fit simple_seq_fit] or
[classref boost::interprocess::rbtree_best_fit rbtree_best_fit] classes.
@@ -5216,7 +5518,7 @@ to be used to identify named objects, we can specify the memory algorithm that w
control dynamically the portions of the memory segment, and we can specify
also the index type that will store the [name pointer, object information] mapping.
We can construct our own index types as explained in
[link boost_interprocess.customizing_boost_interprocess.custom_indexes Building custom indexes] section.
[link interprocess.customizing_interprocess.custom_indexes Building custom indexes] section.
[endsect]
@@ -5372,7 +5674,7 @@ in `boost::interprocess` namespace, but with these little details:
[endsect]
[section:customizing_boost_interprocess Customizing Boost.Interprocess]
[section:customizing_interprocess Customizing Boost.Interprocess]
[section:custom_interprocess_alloc Writing a new shared memory allocation algorithm]
@@ -5757,13 +6059,13 @@ these alternatives:
allocators call `allocate()` only when the pool runs out of nodes. This is pretty
efficient (much more than the current default general-purpose algorithm) and this
can save a lot of memory. See
[link boost_interprocess.stl_allocators_segregated_storage Segregated storage node allocators] and
[link boost_interprocess.stl_allocators_adaptive Adaptive node allocators] for more information.
[link interprocess.stl_allocators_segregated_storage Segregated storage node allocators] and
[link interprocess.stl_allocators_adaptive Adaptive node allocators] for more information.
* Write your own memory algorithm. If you have experience with memory allocation algorithms
and you think another algorithm is better suited than the default one for your application,
you can specify it in all [*Boost.Interprocess] managed memory segments. See the section
[link boost_interprocess.customizing_boost_interprocess.custom_interprocess_alloc Writing a new shared memory allocation algorithm]
[link interprocess.customizing_interprocess.custom_interprocess_alloc Writing a new shared memory allocation algorithm]
to know how to do this. If you think its better than the default one for general-purpose
applications, be polite and donate it to [*Boost.Interprocess] to make it default!
@@ -5842,7 +6144,7 @@ If you see that the performance is not good enough you have these alternatives:
* Use another [*Boost.Interprocess] index type if you feel the default one is
not fast enough. If you are not still satisfied, write your own index type. See
[link boost_interprocess.customizing_boost_interprocess.custom_indexes Building custom indexes] for this.
[link interprocess.customizing_interprocess.custom_indexes Building custom indexes] for this.
* Destruction via pointer is at least as fast as using the name of the object and
can be faster (in node containers, for example). So if your problem is that you
@@ -6007,24 +6309,40 @@ limitations under the License.
[endsect]
[section:changes Changes...]
[section:release_notes Release Notes]
[section:changes_interprocess_2007_06_23 Changes in Interprocess 2007-06-23...]
[section:release_notes_boost_1_35_00 Boost 1.35 Release]
* Reduced template bloat for node and adaptive allocators extracting node
implementation to a class only depends on the memory algorithm, instead of
the segment manager + node size + node number...
* Fixed bug in `mapped_region` in UNIX when mapping address was provided but
the region was mapped in another address.
* Added `aligned_allocate` and `allocate_many` functions to managed memory segments.
* Improved documentation about managed memory segments.
* Added `get_instance_name`, `get_instance_length` and `get_instance_type` functions
to managed memory segments.
* Corrected suboptimal buffer expansion bug in `rbtree_best_fit`.
* Added iteration of named and unique objects in a segment manager.
* Fixed leak in [classref boost::interprocess::vector vector].
* Added support for Solaris.
* Optimized [classref boost::interprocess::segment_manager] to avoid
code bloat associated with templated instantiations.
* Removed the use of allocator::construct and allocator::destroy from containers.
* Optimized [classref boost::interprocess::segment_manager segment_manager]
to avoid code bloat associated with templated instantiations.
* Correction of typos and documentation errors.
* Fixed bug for UNIX: No slash ('/') was being added as the first character
for shared memory names, leading to errors in some UNIX systems.
[endsect]
[section:changes_interprocess_2007_05_03 Changes in Interprocess 2007-05-03...]
* Fixed bug in VC-8.0: Broken function inlining in core offset_ptr functions.
* Code examples changed to use new BoostBook code import features.
@@ -6076,7 +6394,7 @@ limitations under the License.
* Optimized vector to take advantage of `boost::has_trivial_destructor`.
This optimization avoids calling destructors of elements that have a trivial destructor.
* Optimized vector to take advantage of `boost::intrusive::has_trivial_destructor_after_move` trait.
* Optimized vector to take advantage of `has_trivial_destructor_after_move` trait.
This optimization avoids calling destructors of elements that have a trivial destructor
if the element has been moved (which is the case of many movable types). This trick
was provided by Howard Hinnant.
@@ -6108,10 +6426,6 @@ limitations under the License.
* Minor bugfixes.
[endsect]
[section:changes_interprocess_2006_10_13 Changes in Interprocess 2006-10-13...]
* Implemented N1780 proposal to LWG issue 233: ['Insertion hints in associative containers]
in interprocess [classref boost::interprocess::multiset multiset] and
[classref boost::interprocess::multimap multimap] classes.
@@ -6123,7 +6437,7 @@ limitations under the License.
and memory mapped files. This change tries to minimize deadlocks.
* [*Source breaking]: Changed shared memory, memory mapped files and mapped region's
open mode to a single `boost::interprocess::mode_t` type.
open mode to a single `mode_t` type.
* Added extra WIN32_LEAN_AND_MEAN before including DateTime headers to avoid socket
redefinition errors when using Interprocess and Asio in windows.
@@ -6177,7 +6491,7 @@ allocators and containers, I've used to design Interprocess.
* A framework to put STL in shared memory: [@http://allocator.sourceforge.net/ ['"A C++ Standard Allocator for the Standard Template Library"] ].
* A design for instantiating C++ objects in shared memory: [@http://www.cs.ubc.ca/local/reading/proceedings/cascon94/htm/english/abs/hon.htm ['"Using objects in shared memory for C++ application"] ].
* Instantiating C++ objects in shared memory: [@http://www.cs.ubc.ca/local/reading/proceedings/cascon94/htm/english/abs/hon.htm ['"Using objects in shared memory for C++ application"] ].
* A shared memory allocator and relative pointer: [@http://home.earthlink.net/~joshwalker1/writing/SharedMemory.html ['"Taming Shared Memory"] ].
@@ -6185,4 +6499,4 @@ allocators and containers, I've used to design Interprocess.
[endsect]
[xinclude interprocess_doxygen.xml]
[xinclude autodoc.xml]

View File

@@ -49,7 +49,7 @@ int main()
//This allocation will maximize the size of the aligned memory
//and will increase the possibility of finding more aligned memory
ptr = managed_shm.allocate_aligned
(Alignment - managed_shared_memory::PayloadPerAllocation, Alignment);
(3*Alignment - managed_shared_memory::PayloadPerAllocation, Alignment);
//Check alignment
assert(((char*)ptr-(char*)0) % Alignment == 0);

View File

@@ -0,0 +1,87 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2006-2007. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/interprocess for documentation.
//
//////////////////////////////////////////////////////////////////////////////
//[doc_managed_allocation_command
#include <boost/interprocess/managed_shared_memory.hpp>
#include <cassert>
int main()
{
using namespace boost::interprocess;
//Managed memory segment that allocates portions of a shared memory
//segment with the default management algorithm
shared_memory_object::remove("MyManagedShm");
try{
managed_shared_memory managed_shm(create_only, "MyManagedShm", 10000*sizeof(std::size_t));
//Allocate at least 100 bytes, 1000 bytes if possible
std::size_t received_size, min_size = 100, preferred_size = 1000;
std::size_t *ptr = managed_shm.allocation_command<std::size_t>
(allocate_new, min_size, preferred_size, received_size).first;
//Received size must be bigger than min_size
assert(received_size >= min_size);
//Get free memory
std::size_t free_memory_after_allocation = managed_shm.get_free_memory();
//Now write the data
for(std::size_t i = 0; i < received_size; ++i) ptr[i] = i;
//Now try to triplicate the buffer. We won't admit an expansion
//lower to the double of the original buffer.
//This "should" be successful since no other class is allocating
//memory from the segment
std::size_t expanded_size;
std::pair<std::size_t *, bool> ret = managed_shm.allocation_command
(expand_fwd, received_size*2, received_size*3, expanded_size, ptr);
//Check invariants
assert(ret.second == true);
assert(ret.first == ptr);
assert(expanded_size >= received_size*2);
//Get free memory and compare
std::size_t free_memory_after_expansion = managed_shm.get_free_memory();
assert(free_memory_after_expansion < free_memory_after_allocation);
//Write new values
for(std::size_t i = received_size; i < expanded_size; ++i) ptr[i] = i;
//Try to shrink approximately to min_size, but the new size
//should be smaller than min_size*2.
//This "should" be successful since no other class is allocating
//memory from the segment
std::size_t shrunk_size;
ret = managed_shm.allocation_command
(shrink_in_place, min_size*2, min_size, shrunk_size, ptr);
//Check invariants
assert(ret.second == true);
assert(ret.first == ptr);
assert(shrunk_size <= min_size*2);
assert(shrunk_size >= min_size);
//Get free memory and compare
std::size_t free_memory_after_shrinking = managed_shm.get_free_memory();
assert(free_memory_after_shrinking > free_memory_after_expansion);
//Deallocate the buffer
managed_shm.deallocate(ptr);
}
catch(...){
shared_memory_object::remove("MyManagedShm");
throw;
}
shared_memory_object::remove("MyManagedShm");
return 0;
}
//]

View File

@@ -0,0 +1,60 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2006-2007. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/interprocess for documentation.
//
//////////////////////////////////////////////////////////////////////////////
//[doc_managed_construction_info
#include <boost/interprocess/managed_shared_memory.hpp>
#include <cassert>
#include <cstring>
class my_class
{
//...
};
int main()
{
using namespace boost::interprocess;
typedef managed_shared_memory msm;
shared_memory_object::remove("MyManagedShm");
try{
msm managed_shm(create_only, "MyManagedShm", 10000*sizeof(std::size_t));
//Construct objects
my_class *named_object = managed_shm.construct<my_class>("Object name")[1]();
my_class *unique_object = managed_shm.construct<my_class>(unique_instance)[2]();
my_class *anon_object = managed_shm.construct<my_class>(anonymous_instance)[3]();
//Now test "get_instance_name" function.
assert(0 == std::strcmp(msm::get_instance_name(named_object), "Object name"));
assert(0 == msm::get_instance_name(unique_object));
assert(0 == msm::get_instance_name(anon_object));
//Now test "get_instance_type" function.
assert(named_type == msm::get_instance_type(named_object));
assert(unique_type == msm::get_instance_type(unique_object));
assert(anonymous_type == msm::get_instance_type(anon_object));
//Now test "get_instance_length" function.
assert(1 == msm::get_instance_length(named_object));
assert(2 == msm::get_instance_length(unique_object));
assert(3 == msm::get_instance_length(anon_object));
managed_shm.destroy_ptr(named_object);
managed_shm.destroy_ptr(unique_object);
managed_shm.destroy_ptr(anon_object);
}
catch(...){
shared_memory_object::remove("MyManagedShm");
throw;
}
shared_memory_object::remove("MyManagedShm");
return 0;
}
//]

View File

@@ -0,0 +1,64 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2006-2007. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/interprocess for documentation.
//
//////////////////////////////////////////////////////////////////////////////
//[doc_managed_multiple_allocation
#include <boost/interprocess/managed_shared_memory.hpp>
#include <cassert>//assert
#include <cstring>//std::memset
#include <new> //std::nothrow
int main()
{
using namespace boost::interprocess;
typedef managed_shared_memory::multiallocation_iterator multiallocation_iterator;
//Try to erase any previous managed segment with the same name
shared_memory_object::remove("MyManagedShm");
try{
managed_shared_memory managed_shm(create_only, "MyManagedShm", 65536);
std::size_t received_size;
//Allocate 16 elements of 100 bytes in a single call. Non-throwing version.
multiallocation_iterator beg_it = managed_shm.allocate_many(100, 16, 16, received_size, std::nothrow);
//To check for an error, we can use a boolean expresssion
//or compare it with a default constructed iterator
assert(!beg_it == (beg_it == multiallocation_iterator()));
//Check if the memory allocation was successful
if(!beg_it) return 1;
//Initialize our data
for( multiallocation_iterator it = beg_it, end_it; it != end_it; )
std::memset(*it++, 0, 100);
//Now deallocate
for(multiallocation_iterator it = beg_it, end_it; it != end_it;)
managed_shm.deallocate(*it++);
//Allocate 10 buffers of different sizes in a single call. Throwing version
std::size_t sizes[10];
for(std::size_t i = 0; i < 10; ++i)
sizes[i] = i*3;
beg_it = managed_shm.allocate_many(sizes, 10);
//Iterate each allocated buffer and deallocate
//The "end" condition can be also checked with operator!
for(multiallocation_iterator it = beg_it; it;)
managed_shm.deallocate(*it++);
}
catch(...){
shared_memory_object::remove("MyManagedShm");
throw;
}
shared_memory_object::remove("MyManagedShm");
return 0;
}
//]

View File

@@ -31,13 +31,24 @@ int main ()
//Create an object of MyType initialized to {0.0, 0}
MyType *instance = segment.construct<MyType>
("MyType instance") //name of the object
(0.0, 0); //ctor second argument
(0.0, 0); //ctor first argument
//Create an array of 10 elements of MyType initialized to {0.0, 0}
MyType *array = segment.construct<MyType>
("MyType array") //name of the object
[10] //number of elements
(0.0, 0); //ctor second argument
(0.0, 0); //Same two ctor arguments for all objects
//Create an array of 3 elements of MyType initializing each one
//to a different value {0.0, 0}, {1.0, 1}, {2.0, 2}...
float float_initializer[3] = { 0.0, 1.0, 2.0 };
int int_initializer[3] = { 0, 1, 2 };
MyType *array_it = segment.construct_it<MyType>
("MyType array from it") //name of the object
[3] //number of elements
( &float_initializer[0] //Iterator for the 1st ctor argument
, &int_initializer[0]); //Iterator for the 2nd ctor argument
}
catch(...){
shared_memory_object::remove("MySharedMemory");

View File

@@ -27,30 +27,30 @@ int main ()
//and initialize needed resources
managed_shared_memory segment(open_only, "MySharedMemory");
//Find the array and object
std::pair<MyType*, std::size_t> res;
//Find the array
res = segment.find<MyType> ("MyType array");
std::size_t array_len = res.second;
//Length should be 10
assert(array_len == 10);
assert(res.second == 10);
//Find the array and the object
//Find the object
res = segment.find<MyType> ("MyType instance");
std::size_t len = res.second;
//Length should be 1
assert(len == 1);
assert(res.second == 1);
//Find the array constructed from iterators
res = segment.find<MyType> ("MyType array from it");
//Length should be 3
assert(res.second == 3);
//Use data
// . . .
//We're done, delete array from memory
//We're done, delete all the objects
segment.destroy<MyType>("MyType array");
//We're done, delete object from memory
segment.destroy<MyType>("MyType instance");
segment.destroy<MyType>("MyType array from it");
}
catch(...){
shared_memory_object::remove("MySharedMemory");

View File

@@ -4,6 +4,6 @@
</head>
<body>
Automatic redirection failed, please go to
<a href="../../../doc/html/interprocess.html">../../doc/html/interprocess.html</a>
<a href="../../doc/html/interprocess.html">../../doc/html/interprocess.html</a>
</body>
</html>

View File

@@ -379,6 +379,18 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "semaphore_test", "semaphore
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_managed_multiple_allocation", "doc_managed_multiple_allocation.vcproj", "{818C43EE-3561-F3AE-4FD7-8A2076E76A31}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_managed_allocation_command", "doc_managed_allocation_command.vcproj", "{5189DEA3-3261-F33E-47ED-83BC69F66061}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "doc_managed_construction_info", "doc_managed_construction_info.vcproj", "{5C82D1D3-3861-3AF1-03EF-89AED4716761}"
ProjectSection(ProjectDependencies) = postProject
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfiguration) = preSolution
Debug = Debug
@@ -767,6 +779,18 @@ Global
{5CE28C83-48FE-1676-4FA7-B50D3A76A013}.Debug.Build.0 = Debug|Win32
{5CE28C83-48FE-1676-4FA7-B50D3A76A013}.Release.ActiveCfg = Release|Win32
{5CE28C83-48FE-1676-4FA7-B50D3A76A013}.Release.Build.0 = Release|Win32
{818C43EE-3561-F3AE-4FD7-8A2076E76A31}.Debug.ActiveCfg = Debug|Win32
{818C43EE-3561-F3AE-4FD7-8A2076E76A31}.Debug.Build.0 = Debug|Win32
{818C43EE-3561-F3AE-4FD7-8A2076E76A31}.Release.ActiveCfg = Release|Win32
{818C43EE-3561-F3AE-4FD7-8A2076E76A31}.Release.Build.0 = Release|Win32
{5189DEA3-3261-F33E-47ED-83BC69F66061}.Debug.ActiveCfg = Debug|Win32
{5189DEA3-3261-F33E-47ED-83BC69F66061}.Debug.Build.0 = Debug|Win32
{5189DEA3-3261-F33E-47ED-83BC69F66061}.Release.ActiveCfg = Release|Win32
{5189DEA3-3261-F33E-47ED-83BC69F66061}.Release.Build.0 = Release|Win32
{5C82D1D3-3861-3AF1-03EF-89AED4716761}.Debug.ActiveCfg = Debug|Win32
{5C82D1D3-3861-3AF1-03EF-89AED4716761}.Debug.Build.0 = Debug|Win32
{5C82D1D3-3861-3AF1-03EF-89AED4716761}.Release.ActiveCfg = Release|Win32
{5C82D1D3-3861-3AF1-03EF-89AED4716761}.Release.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
EndGlobalSection

View File

@@ -0,0 +1,134 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="doc_managed_allocation_command"
ProjectGUID="{5189DEA3-3261-F33E-47ED-83BC69F66061}"
Keyword="Win32Proj">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="../../Bin/Win32/Debug"
IntermediateDirectory="Debug/doc_managed_allocation_command"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="../../../.."
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="winmm.lib"
OutputFile="$(OutDir)/doc_managed_allocation_command_d.exe"
LinkIncremental="1"
AdditionalLibraryDirectories="../../../../stage/lib"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile="$(OutDir)/doc_managed_allocation_command.pdb"
SubSystem="1"
TargetMachine="1"
FixedBaseAddress="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="../../Bin/Win32/Release"
IntermediateDirectory="Release/doc_managed_allocation_command"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="../../../.."
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
RuntimeLibrary="2"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="0"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="winmm.lib"
OutputFile="$(OutDir)/doc_managed_allocation_command.exe"
LinkIncremental="1"
AdditionalLibraryDirectories="../../../../stage/lib"
GenerateDebugInformation="TRUE"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4F368471-DA5A-4367-0A86-613645FBF23D}">
<File
RelativePath="..\..\example\doc_managed_allocation_command.cpp">
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{53F54618-D3BA-1D51-A89E-E51FABD7E2FB}">
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@@ -0,0 +1,134 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="doc_managed_construction_info"
ProjectGUID="{5C82D1D3-3861-3AF1-03EF-89AED4716761}"
Keyword="Win32Proj">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="../../Bin/Win32/Debug"
IntermediateDirectory="Debug/doc_managed_construction_info"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="../../../.."
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="winmm.lib"
OutputFile="$(OutDir)/doc_managed_construction_info_d.exe"
LinkIncremental="1"
AdditionalLibraryDirectories="../../../../stage/lib"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile="$(OutDir)/doc_managed_construction_info.pdb"
SubSystem="1"
TargetMachine="1"
FixedBaseAddress="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="../../Bin/Win32/Release"
IntermediateDirectory="Release/doc_managed_construction_info"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="../../../.."
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
RuntimeLibrary="2"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="0"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="winmm.lib"
OutputFile="$(OutDir)/doc_managed_construction_info.exe"
LinkIncremental="1"
AdditionalLibraryDirectories="../../../../stage/lib"
GenerateDebugInformation="TRUE"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4BD7F471-DA5A-4367-0A86-611E94F5FA5E}">
<File
RelativePath="..\..\example\doc_managed_construction_info.cpp">
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{55274F38-8C8B-D461-55EB-E53642BF23FB}">
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@@ -0,0 +1,136 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="doc_managed_multiple_allocation"
ProjectGUID="{818C43EE-3561-F3AE-4FD7-8A2076E76A31}"
Keyword="Win32Proj">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="../../Bin/Win32/Debug"
IntermediateDirectory="Debug/doc_managed_multiple_allocation"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="../../../.."
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
DisableLanguageExtensions="FALSE"
ForceConformanceInForLoopScope="TRUE"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="winmm.lib"
OutputFile="$(OutDir)/doc_managed_multiple_allocation_d.exe"
LinkIncremental="1"
AdditionalLibraryDirectories="../../../../stage/lib"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile="$(OutDir)/doc_managed_multiple_allocation.pdb"
SubSystem="1"
TargetMachine="1"
FixedBaseAddress="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="../../Bin/Win32/Release"
IntermediateDirectory="Release/doc_managed_multiple_allocation"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="../../../.."
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
RuntimeLibrary="2"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="0"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="winmm.lib"
OutputFile="$(OutDir)/doc_managed_multiple_allocation.exe"
LinkIncremental="1"
AdditionalLibraryDirectories="../../../../stage/lib"
GenerateDebugInformation="TRUE"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{48F54471-DA5A-4367-0A86-6A5D22FEA7FF}">
<File
RelativePath="..\..\example\doc_managed_multiple_allocation.cpp">
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{53F36518-6D8C-3B17-8B71-D5632DF213FB}">
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@@ -173,6 +173,9 @@
<File
RelativePath="..\..\..\..\boost\interprocess\containers\detail\flat_tree.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\interprocess\containers\detail\node_alloc_holder.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\interprocess\containers\detail\tree.hpp">
</File>
@@ -349,6 +352,9 @@
Name="Managed Memory Classes"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
<File
RelativePath="..\..\..\..\boost\interprocess\creation_tags.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\interprocess\errors.hpp">
</File>
@@ -367,9 +373,6 @@
<File
RelativePath="..\..\..\..\boost\interprocess\managed_mapped_file.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\interprocess\managed_multi_shared_memory.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\interprocess\managed_shared_memory.hpp">
</File>
@@ -410,12 +413,6 @@
<File
RelativePath="..\..\..\..\boost\interprocess\detail\config_end.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\interprocess\detail\construction_table.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\interprocess\detail\creation_tags.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\interprocess\detail\file_wrapper.hpp">
</File>
@@ -443,9 +440,6 @@
<File
RelativePath="..\..\..\..\boost\interprocess\detail\move_iterator.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\interprocess\detail\moved_default_iterator.hpp">
</File>
<File
RelativePath="..\..\..\..\boost\interprocess\detail\mpl.hpp">
</File>
@@ -563,6 +557,9 @@
<File
RelativePath="..\..\test\expand_bwd_test_template.hpp">
</File>
<File
RelativePath="..\..\test\get_compiler_name.hpp">
</File>
<File
RelativePath="..\..\test\itestvalue.hpp">
</File>

View File

@@ -1,134 +1,134 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="memory_algorithm_test"
ProjectGUID="{58E18CC3-6092-8F4E-A3E7-A792230D3629}"
Keyword="Win32Proj">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="../../Bin/Win32/Debug"
IntermediateDirectory="Debug/memory_algorithm_test"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="../../../.."
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="winmm.lib"
OutputFile="$(OutDir)/memory_algorithm_test_d.exe"
LinkIncremental="1"
AdditionalLibraryDirectories="../../../../stage/lib"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile="$(OutDir)/memory_algorithm_test.pdb"
SubSystem="1"
TargetMachine="1"
FixedBaseAddress="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="../../Bin/Win32/Release"
IntermediateDirectory="Release/memory_algorithm_test"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="../../../.."
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
RuntimeLibrary="2"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="0"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="winmm.lib"
OutputFile="$(OutDir)/memory_algorithm_test.exe"
LinkIncremental="1"
AdditionalLibraryDirectories="../../../../stage/lib"
GenerateDebugInformation="TRUE"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{399570F1-7AB7-4376-06A6-D752A2A322FF}">
<File
RelativePath="..\..\test\memory_algorithm_test.cpp">
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{94FF3380-9B3D-4b05-88FA-6FAF2552EB01}">
</Filter>
</Files>
<Globals>
</Globals>
ProjectType="Visual C++"
Version="7.10"
Name="memory_algorithm_test"
ProjectGUID="{58E18CC3-6092-8F4E-A3E7-A792230D3629}"
Keyword="Win32Proj">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory="../../Bin/Win32/Debug"
IntermediateDirectory="Debug/memory_algorithm_test"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="../../../.."
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="3"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="3"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="winmm.lib"
OutputFile="$(OutDir)/memory_algorithm_test_d.exe"
LinkIncremental="1"
AdditionalLibraryDirectories="../../../../stage/lib"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile="$(OutDir)/memory_algorithm_test.pdb"
SubSystem="1"
TargetMachine="1"
FixedBaseAddress="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory="../../Bin/Win32/Release"
IntermediateDirectory="Release/memory_algorithm_test"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="../../../.."
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;BOOST_DATE_TIME_NO_LIB"
RuntimeLibrary="2"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="0"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="winmm.lib"
OutputFile="$(OutDir)/memory_algorithm_test.exe"
LinkIncremental="1"
AdditionalLibraryDirectories="../../../../stage/lib"
GenerateDebugInformation="TRUE"
SubSystem="1"
OptimizeReferences="2"
EnableCOMDATFolding="2"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{399570F1-7AB7-4376-06A6-D752A2A322FF}">
<File
RelativePath="..\..\test\memory_algorithm_test.cpp">
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{94FF3380-9B3D-4b05-88FA-6FAF2552EB01}">
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@@ -17,6 +17,8 @@
#include <algorithm>
#include <functional>
#include "print_container.hpp"
#include <string>
#include "get_compiler_name.hpp"
struct InstanceCounter
{
@@ -34,7 +36,7 @@ using namespace boost::interprocess;
int main ()
{
const int memsize = 16384;
const char *const shMemName = "MySharedMemory";
const char *const shMemName = test::get_compiler_name();
try{
shared_memory_object::remove(shMemName);

View File

@@ -16,14 +16,20 @@
#include <iostream>
#include <algorithm>
#include <functional>
#include <string>
#include "print_container.hpp"
#include "get_compiler_name.hpp"
using namespace boost::interprocess;
int main ()
{
const int memsize = 65536;
const char *const shMemName = "MySharedMemory";
std::string compiler_name;
test::get_compiler_name(compiler_name);
const char *const shMemName = compiler_name.c_str();
std::string filename (test::get_compiler_name());
filename += "_file";
try{
shared_memory_object::remove(shMemName);
@@ -75,7 +81,7 @@ int main ()
//Construct, dump to a file
shmem_vect = segment.construct<MyVect> (allocName) (myallocator);
segment.save_to_file("shmem_file");
segment.save_to_file(filename.c_str());
/*
//Recreate objects in a new shared memory check object is present
@@ -91,11 +97,11 @@ int main ()
if(!res)
return 1;
*/
std::remove("shmem_file");
std::remove(filename.c_str());
}
}
catch(...){
std::remove("shmem_file");
std::remove(filename.c_str());
shared_memory_object::remove(shMemName);
throw;
}

View File

@@ -28,6 +28,8 @@
#include <boost/interprocess/detail/move_iterator.hpp>
#include <boost/interprocess/detail/move.hpp>
#include <boost/interprocess/detail/mpl.hpp>
#include <string>
#include "get_compiler_name.hpp"
//***************************************************************//
// //
@@ -94,7 +96,7 @@ bool do_test()
typedef deque<IntType, shmem_allocator_t> MyShmDeque;
typedef std::deque<int> MyStdDeque;
const int Memsize = 65536;
const char *const shMemName = "MySharedMemory";
const char *const shMemName = test::get_compiler_name();
const int max = 100;
try{
@@ -194,6 +196,10 @@ bool do_test()
segment.template destroy<MyShmDeque>("MyShmDeque");
delete stddeque;
segment.shrink_to_fit_indexes();
if(!segment.all_memory_deallocated())
return 1;
}
catch(std::exception &ex){
std::cout << ex.what() << std::endl;

View File

@@ -65,7 +65,7 @@ class dummy_test_allocator
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
typedef detail::version_type<dummy_test_allocator, 2> version;
// typedef detail::version_type<dummy_test_allocator, 2> version;
template<class T2>
struct rebind

View File

@@ -126,7 +126,7 @@ class expand_bwd_test_allocator
size_type preferred_size,
size_type &received_size, const pointer &reuse = 0)
{
(void)preferred_size; (void)reuse;
(void)preferred_size; (void)reuse; (void)command;
//This allocator only expands backwards!
assert(m_allocations == 0 || (command & expand_bwd));

View File

@@ -15,6 +15,8 @@
#include <boost/interprocess/mapped_region.hpp>
#include <memory>
#include <cstdio>
#include <string>
#include "get_compiler_name.hpp"
using namespace boost::interprocess;
@@ -24,14 +26,14 @@ int main ()
const std::size_t FileSize = 99999*2;
{
//Create file with given size
std::ofstream file("my_file", std::ios::binary | std::ios::trunc);
std::ofstream file(test::get_compiler_name(), std::ios::binary | std::ios::trunc);
file.seekp(static_cast<std::streamoff>(FileSize-1));
file.write("", 1);
}
{
//Create a file mapping
file_mapping mapping("my_file", read_write);
file_mapping mapping(test::get_compiler_name(), read_write);
//Create two mapped regions, one half of the file each
mapped_region region (mapping
,read_write
@@ -64,7 +66,7 @@ int main ()
//See if the pattern is correct in the file
{
//Open the file
std::ifstream file("my_file", std::ios::binary);
std::ifstream file(test::get_compiler_name(), std::ios::binary);
//Create a memory buffer
std::auto_ptr<unsigned char> memory (new unsigned char [FileSize/2 +1]);
@@ -101,7 +103,7 @@ int main ()
//Now check the pattern mapping a single read only mapped_region
{
//Create a file mapping
file_mapping mapping("my_file", read_only);
file_mapping mapping(test::get_compiler_name(), read_only);
//Create a single regions, mapping all the file
mapped_region region (mapping
@@ -120,11 +122,11 @@ int main ()
}
}
catch(std::exception &exc){
std::remove("my_file");
std::remove(test::get_compiler_name());
std::cout << "Unhandled exception: " << exc.what() << std::endl;
throw;
}
std::remove("my_file");
std::remove(test::get_compiler_name());
return 0;
}

View File

@@ -166,17 +166,3 @@ int main()
}
#include <boost/interprocess/detail/config_end.hpp>
/*
//#include <boost/interprocess/shared_memory_object.hpp>
//#include <boost/interprocess/detail/posix_time_types_wrk.hpp>
//#include <boost/operators.hpp>
*/
/*
//#define WIN32_LEAN_AND_MEAN
//#define BOOST_USE_WINDOWS_H
#include <boost/date_time/microsec_time_clock.hpp>
#include <boost/date_time/posix_time/ptime.hpp>
//#include <boost/shared_ptr.hpp>
*/

View File

@@ -0,0 +1,48 @@
//////////////////////////////////////////////////////////////////////////////
//
// (C) Copyright Ion Gaztanaga 2004-2007. Distributed under the Boost
// Software License, Version 1.0. (See accompanying file
// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org/libs/interprocess for documentation.
//
//////////////////////////////////////////////////////////////////////////////
#ifndef BOOST_GET_COMPILER_NAME_HPP
#define BOOST_GET_COMPILER_NAME_HPP
#include <boost/config.hpp>
#include <string>
#include <algorithm>
namespace boost{
namespace interprocess{
namespace test{
inline void get_compiler_name(std::string &str)
{
str = BOOST_COMPILER;
std::replace(str.begin(), str.end(), ' ', '_');
std::replace(str.begin(), str.end(), '.', '_');
}
inline const char *get_compiler_name()
{
static std::string str;
get_compiler_name(str);
return str.c_str();
}
inline const char *add_to_compiler_name(const char *name)
{
static std::string str;
get_compiler_name(str);
str += name;
return str.c_str();
}
} //namespace test{
} //namespace interprocess{
} //namespace boost{
#endif //#ifndef BOOST_GET_COMPILER_NAME_HPP

View File

@@ -20,6 +20,8 @@
#include "print_container.hpp"
#include <boost/interprocess/detail/move.hpp>
#include <boost/interprocess/detail/move_iterator.hpp>
#include <string>
#include "get_compiler_name.hpp"
namespace boost{
namespace interprocess{
@@ -92,146 +94,155 @@ int list_test (bool copied_allocators_equal = true)
typedef std::list<int> MyStdList;
typedef typename MyShmList::value_type IntType;
const int memsize = 65536;
const char *const shMemName = "MySharedMemory";
const char *const shMemName = test::get_compiler_name();
const int max = 100;
typedef push_data_function<DoublyLinked> push_data_t;
try{
//Named new capable shared mem allocator
//Create shared memory
shared_memory_object::remove(shMemName);
ManagedSharedMemory segment(create_only, shMemName, memsize);
//Named new capable shared mem allocator
//Create shared memory
shared_memory_object::remove(shMemName);
ManagedSharedMemory segment(create_only, shMemName, memsize);
segment.reserve_named_objects(100);
segment.reserve_named_objects(100);
//Shared memory allocator must be always be initialized
//since it has no default constructor
MyShmList *shmlist = segment.template construct<MyShmList>("MyList")
(segment.get_segment_manager());
//Shared memory allocator must be always be initialized
//since it has no default constructor
MyShmList *shmlist = segment.template construct<MyShmList>("MyList")
(segment.get_segment_manager());
MyStdList *stdlist = new MyStdList;
MyStdList *stdlist = new MyStdList;
if(push_data_t::execute(max, shmlist, stdlist)){
return 1;
}
shmlist->erase(shmlist->begin()++);
stdlist->erase(stdlist->begin()++);
if(!CheckEqualContainers(shmlist, stdlist)) return 1;
if(pop_back_function<DoublyLinked>::execute(shmlist, stdlist)){
return 1;
}
shmlist->pop_front();
stdlist->pop_front();
if(!CheckEqualContainers(shmlist, stdlist)) return 1;
{
IntType aux_vect[50];
for(int i = 0; i < 50; ++i){
IntType move_me(-1);
aux_vect[i] = move(move_me);
if(push_data_t::execute(max, shmlist, stdlist)){
return 1;
}
int aux_vect2[50];
for(int i = 0; i < 50; ++i){
aux_vect2[i] = -1;
}
shmlist->assign(detail::make_move_iterator(&aux_vect[0])
,detail::make_move_iterator(&aux_vect[50]));
stdlist->assign(&aux_vect2[0], &aux_vect2[50]);
if(!CheckEqualContainers(shmlist, stdlist)) return 1;
}
if(copied_allocators_equal){
shmlist->sort();
stdlist->sort();
if(!CheckEqualContainers(shmlist, stdlist)) return 1;
}
shmlist->reverse();
stdlist->reverse();
if(!CheckEqualContainers(shmlist, stdlist)) return 1;
shmlist->reverse();
stdlist->reverse();
if(!CheckEqualContainers(shmlist, stdlist)) return 1;
{
IntType aux_vect[50];
for(int i = 0; i < 50; ++i){
IntType move_me(-1);
aux_vect[i] = move(move_me);
}
int aux_vect2[50];
for(int i = 0; i < 50; ++i){
aux_vect2[i] = -1;
}
shmlist->insert(shmlist->begin()
,detail::make_move_iterator(&aux_vect[0])
,detail::make_move_iterator(&aux_vect[50]));
stdlist->insert(stdlist->begin(), &aux_vect2[0], &aux_vect2[50]);
}
shmlist->unique();
stdlist->unique();
if(!CheckEqualContainers(shmlist, stdlist)) return 1;
if(copied_allocators_equal){
shmlist->sort(std::greater<IntType>());
stdlist->sort(std::greater<int>());
if(!CheckEqualContainers(shmlist, stdlist)) return 1;
}
shmlist->resize(shmlist->size()/2);
stdlist->resize(stdlist->size()/2);
if(!CheckEqualContainers(shmlist, stdlist)) return 1;
if(push_data_t::execute(max, shmlist, stdlist)){
return 1;
}
MyShmList othershmlist(shmlist->get_allocator());
MyStdList otherstdlist;
int listsize = (int)shmlist->size();
if(push_data_t::execute(listsize, shmlist, stdlist)){
return 1;
}
if(copied_allocators_equal){
shmlist->splice(shmlist->begin(), othershmlist);
stdlist->splice(stdlist->begin(), otherstdlist);
if(!CheckEqualContainers(shmlist, stdlist)) return 1;
}
listsize = (int)shmlist->size();
if(push_data_t::execute(listsize, shmlist, stdlist)){
return 1;
}
if(push_data_t::execute(listsize, &othershmlist, &otherstdlist)){
return 1;
}
if(copied_allocators_equal){
shmlist->sort(std::greater<IntType>());
stdlist->sort(std::greater<int>());
shmlist->erase(shmlist->begin()++);
stdlist->erase(stdlist->begin()++);
if(!CheckEqualContainers(shmlist, stdlist)) return 1;
othershmlist.sort(std::greater<IntType>());
otherstdlist.sort(std::greater<int>());
if(!CheckEqualContainers(&othershmlist, &otherstdlist)) return 1;
if(pop_back_function<DoublyLinked>::execute(shmlist, stdlist)){
return 1;
}
shmlist->merge(othershmlist, std::greater<IntType>());
stdlist->merge(otherstdlist, std::greater<int>());
if(!CheckEqualContainers(shmlist, stdlist)) return 1;
}
shmlist->pop_front();
stdlist->pop_front();
if(!CheckEqualContainers(shmlist, stdlist)) return 1;
segment.template destroy<MyShmList>("MyList");
delete stdlist;
{
IntType aux_vect[50];
for(int i = 0; i < 50; ++i){
IntType move_me(-1);
aux_vect[i] = move(move_me);
}
int aux_vect2[50];
for(int i = 0; i < 50; ++i){
aux_vect2[i] = -1;
}
shmlist->assign(detail::make_move_iterator(&aux_vect[0])
,detail::make_move_iterator(&aux_vect[50]));
stdlist->assign(&aux_vect2[0], &aux_vect2[50]);
if(!CheckEqualContainers(shmlist, stdlist)) return 1;
}
if(copied_allocators_equal){
shmlist->sort();
stdlist->sort();
if(!CheckEqualContainers(shmlist, stdlist)) return 1;
}
shmlist->reverse();
stdlist->reverse();
if(!CheckEqualContainers(shmlist, stdlist)) return 1;
shmlist->reverse();
stdlist->reverse();
if(!CheckEqualContainers(shmlist, stdlist)) return 1;
{
IntType aux_vect[50];
for(int i = 0; i < 50; ++i){
IntType move_me(-1);
aux_vect[i] = move(move_me);
}
int aux_vect2[50];
for(int i = 0; i < 50; ++i){
aux_vect2[i] = -1;
}
shmlist->insert(shmlist->begin()
,detail::make_move_iterator(&aux_vect[0])
,detail::make_move_iterator(&aux_vect[50]));
stdlist->insert(stdlist->begin(), &aux_vect2[0], &aux_vect2[50]);
}
shmlist->unique();
stdlist->unique();
if(!CheckEqualContainers(shmlist, stdlist)) return 1;
if(copied_allocators_equal){
shmlist->sort(std::greater<IntType>());
stdlist->sort(std::greater<int>());
if(!CheckEqualContainers(shmlist, stdlist)) return 1;
}
shmlist->resize(25);
stdlist->resize(25);
shmlist->resize(50);
stdlist->resize(50);
shmlist->resize(0);
stdlist->resize(0);
if(!CheckEqualContainers(shmlist, stdlist)) return 1;
if(push_data_t::execute(max, shmlist, stdlist)){
return 1;
}
{
MyShmList othershmlist(shmlist->get_allocator());
MyStdList otherstdlist;
int listsize = (int)shmlist->size();
if(push_data_t::execute(listsize, shmlist, stdlist)){
return 1;
}
if(copied_allocators_equal){
shmlist->splice(shmlist->begin(), othershmlist);
stdlist->splice(stdlist->begin(), otherstdlist);
if(!CheckEqualContainers(shmlist, stdlist)) return 1;
}
listsize = (int)shmlist->size();
if(push_data_t::execute(listsize, shmlist, stdlist)){
return 1;
}
if(push_data_t::execute(listsize, &othershmlist, &otherstdlist)){
return 1;
}
if(copied_allocators_equal){
shmlist->sort(std::greater<IntType>());
stdlist->sort(std::greater<int>());
if(!CheckEqualContainers(shmlist, stdlist)) return 1;
othershmlist.sort(std::greater<IntType>());
otherstdlist.sort(std::greater<int>());
if(!CheckEqualContainers(&othershmlist, &otherstdlist)) return 1;
shmlist->merge(othershmlist, std::greater<IntType>());
stdlist->merge(otherstdlist, std::greater<int>());
if(!CheckEqualContainers(shmlist, stdlist)) return 1;
}
}
segment.template destroy<MyShmList>("MyList");
delete stdlist;
segment.shrink_to_fit_indexes();
if(!segment.all_memory_deallocated())
return 1;
}
catch(...){
shared_memory_object::remove(shMemName);

View File

@@ -13,13 +13,15 @@
#include <boost/interprocess/containers/vector.hpp>
#include <boost/interprocess/managed_mapped_file.hpp>
#include <cstdio>
#include <string>
#include "get_compiler_name.hpp"
using namespace boost::interprocess;
int main ()
{
const int FileSize = 65536;
const char *const FileName = "MyMappedFile";
const char *const FileName = test::get_compiler_name();
//STL compatible allocator object for memory-mapped file
typedef allocator<int, managed_mapped_file::segment_manager>

View File

@@ -16,13 +16,15 @@
#include <boost/interprocess/containers/vector.hpp>
#include <boost/interprocess/managed_windows_shared_memory.hpp>
#include <cstdio>
#include <string>
#include "get_compiler_name.hpp"
using namespace boost::interprocess;
int main ()
{
const int MemSize = 65536;
const char *const MemName = "MySharedMemory";
const char *const MemName = test::get_compiler_name();
//STL compatible allocator object for shared memory
typedef allocator<int, managed_windows_shared_memory::segment_manager>

View File

@@ -20,6 +20,8 @@
#include <boost/interprocess/detail/move_iterator.hpp>
#include <boost/interprocess/detail/utilities.hpp>
#include <boost/interprocess/detail/iterators.hpp>
#include <string>
#include "get_compiler_name.hpp"
template<class T1, class T2, class T3, class T4>
bool operator ==(std::pair<T1, T2> &p1, std::pair<T1, T2> &p2)
@@ -42,274 +44,279 @@ int map_test ()
typedef std::pair<IntType, IntType> IntPairType;
typedef typename MyStdMap::value_type StdPairType;
const int memsize = 65536;
const char *const shMemName = "/MySharedMemory";
const char *const shMemName = test::get_compiler_name();
const int max = 100;
try{
//Create shared memory
shared_memory_object::remove(shMemName);
ManagedSharedMemory segment(create_only, shMemName, memsize);
//Create shared memory
shared_memory_object::remove(shMemName);
ManagedSharedMemory segment(create_only, shMemName, memsize);
segment.reserve_named_objects(100);
segment.reserve_named_objects(100);
//Shared memory allocator must be always be initialized
//since it has no default constructor
MyShmMap *shmmap =
segment.template construct<MyShmMap>("MyShmMap")
(std::less<IntType>(), segment.get_segment_manager());
//Shared memory allocator must be always be initialized
//since it has no default constructor
MyShmMap *shmmap =
segment.template construct<MyShmMap>("MyShmMap")
(std::less<IntType>(), segment.get_segment_manager());
MyStdMap *stdmap = new MyStdMap;
MyStdMap *stdmap = new MyStdMap;
MyShmMultiMap *shmmultimap =
segment.template construct<MyShmMultiMap>("MyShmMultiMap")
(std::less<IntType>(), segment.get_segment_manager());
MyShmMultiMap *shmmultimap =
segment.template construct<MyShmMultiMap>("MyShmMultiMap")
(std::less<IntType>(), segment.get_segment_manager());
MyStdMultiMap *stdmultimap = new MyStdMultiMap;
MyStdMultiMap *stdmultimap = new MyStdMultiMap;
//Test construction from a range
{
//This is really nasty, but we have no other simple choice
IntPairType aux_vect[50];
for(int i = 0; i < 50; ++i){
new(&aux_vect[i])IntPairType(IntType(i/2), IntType(i/2));
//Test construction from a range
{
//This is really nasty, but we have no other simple choice
IntPairType aux_vect[50];
for(int i = 0; i < 50; ++i){
new(&aux_vect[i])IntPairType(IntType(i/2), IntType(i/2));
}
typedef typename MyStdMap::value_type StdValueType;
typedef typename MyStdMap::key_type StdKeyType;
typedef typename MyStdMap::mapped_type StdMappedType;
StdValueType aux_vect2[50];
for(int i = 0; i < 50; ++i){
new(&aux_vect2[i])StdValueType(StdKeyType(i/2), StdMappedType(i/2));
}
IntPairType aux_vect3[50];
for(int i = 0; i < 50; ++i){
new(&aux_vect3[i])IntPairType(IntType(i/2), IntType(i/2));
}
MyShmMap *shmmap2 =
segment.template construct<MyShmMap>("MyShmMap2")
(detail::make_move_iterator(&aux_vect[0])
, detail::make_move_iterator(aux_vect + 50)
, std::less<IntType>(), segment.get_segment_manager());
MyStdMap *stdmap2 = new MyStdMap(aux_vect2, aux_vect2 + 50);
MyShmMultiMap *shmmultiset2 =
segment.template construct<MyShmMultiMap>("MyShmMultiMap2")
(detail::make_move_iterator(&aux_vect3[0])
, detail::make_move_iterator(aux_vect3 + 50)
, std::less<IntType>(), segment.get_segment_manager());
MyStdMultiMap *stdmultiset2 = new MyStdMultiMap(aux_vect2, aux_vect2 + 50);
if(!CheckEqualContainers(shmmap2, stdmap2)) return 1;
if(!CheckEqualContainers(shmmultiset2, stdmultiset2)) return 1;
segment.destroy_ptr(shmmap2);
segment.destroy_ptr(shmmultiset2);
delete stdmap2;
delete stdmultiset2;
}
typedef typename MyStdMap::value_type StdValueType;
typedef typename MyStdMap::key_type StdKeyType;
typedef typename MyStdMap::mapped_type StdMappedType;
StdValueType aux_vect2[50];
for(int i = 0; i < 50; ++i){
new(&aux_vect2[i])StdValueType(StdKeyType(i/2), StdMappedType(i/2));
int i, j;
for(i = 0; i < max; ++i){
shmmap->insert(move(IntPairType (move(IntType(i)), move(IntType(i)))));
stdmap->insert(StdPairType(i, i));
shmmultimap->insert(move(IntPairType(move(IntType(i)), move(IntType(i)))));
stdmultimap->insert(StdPairType(i, i));
}
IntPairType aux_vect3[50];
for(int i = 0; i < 50; ++i){
new(&aux_vect3[i])IntPairType(IntType(i/2), IntType(i/2));
}
MyShmMap *shmset2 =
segment.template construct<MyShmMap>("MyShmMap2")
(detail::make_move_iterator(&aux_vect[0])
, detail::make_move_iterator(aux_vect + 50)
, std::less<IntType>(), segment.get_segment_manager());
MyStdMap *stdset2 = new MyStdMap(aux_vect2, aux_vect2 + 50);
MyShmMultiMap *shmmultiset2 =
segment.template construct<MyShmMultiMap>("MyShmMultiMap2")
(detail::make_move_iterator(&aux_vect3[0])
, detail::make_move_iterator(aux_vect3 + 50)
, std::less<IntType>(), segment.get_segment_manager());
MyStdMultiMap *stdmultiset2 = new MyStdMultiMap(aux_vect2, aux_vect2 + 50);
if(!CheckEqualContainers(shmset2, stdset2)) return 1;
if(!CheckEqualContainers(shmmultiset2, stdmultiset2)) return 1;
segment.destroy_ptr(shmset2);
segment.destroy_ptr(shmmultiset2);
delete stdset2;
delete stdmultiset2;
}
int i, j;
for(i = 0; i < max; ++i){
shmmap->insert(move(IntPairType (move(IntType(i)), move(IntType(i)))));
stdmap->insert(StdPairType(i, i));
shmmultimap->insert(move(IntPairType(move(IntType(i)), move(IntType(i)))));
stdmultimap->insert(StdPairType(i, i));
}
if(!CheckEqualPairContainers(shmmap, stdmap)) return 1;
if(!CheckEqualPairContainers(shmmultimap, stdmultimap)) return 1;
typename MyShmMap::iterator it;
typename MyShmMap::const_iterator cit = it;
shmmap->erase(shmmap->begin()++);
stdmap->erase(stdmap->begin()++);
shmmultimap->erase(shmmultimap->begin()++);
stdmultimap->erase(stdmultimap->begin()++);
if(!CheckEqualPairContainers(shmmap, stdmap)) return 1;
if(!CheckEqualPairContainers(shmmultimap, stdmultimap)) return 1;
shmmap->erase(shmmap->begin());
stdmap->erase(stdmap->begin());
shmmultimap->erase(shmmultimap->begin());
stdmultimap->erase(stdmultimap->begin());
if(!CheckEqualPairContainers(shmmap, stdmap)) return 1;
if(!CheckEqualPairContainers(shmmultimap, stdmultimap)) return 1;
//Swapping test
std::less<IntType> lessfunc;
MyShmMap tmpshmemap2 (lessfunc, segment.get_segment_manager());
MyStdMap tmpstdmap2;
MyShmMultiMap tmpshmemultimap2(lessfunc, segment.get_segment_manager());
MyStdMultiMap tmpstdmultimap2;
shmmap->swap(tmpshmemap2);
stdmap->swap(tmpstdmap2);
shmmultimap->swap(tmpshmemultimap2);
stdmultimap->swap(tmpstdmultimap2);
shmmap->swap(tmpshmemap2);
stdmap->swap(tmpstdmap2);
shmmultimap->swap(tmpshmemultimap2);
stdmultimap->swap(tmpstdmultimap2);
if(!CheckEqualPairContainers(shmmap, stdmap)) return 1;
if(!CheckEqualPairContainers(shmmultimap, stdmultimap)) return 1;
//Insertion from other container
//Initialize values
{
//This is really nasty, but we have no other simple choice
IntPairType aux_vect[50];
for(int i = 0; i < 50; ++i){
new(&aux_vect[i])IntPairType(IntType(-1), IntType(-1));
}
IntPairType aux_vect3[50];
for(int i = 0; i < 50; ++i){
new(&aux_vect3[i])IntPairType(IntType(-1), IntType(-1));
}
shmmap->insert(detail::make_move_iterator(&aux_vect[0]), detail::make_move_iterator(aux_vect + 50));
StdPairType stdpairtype(-1, -1);
constant_iterator<StdPairType> constant_beg(stdpairtype, 50), constant_end;
stdmap->insert(constant_beg, constant_end);
shmmultimap->insert(detail::make_move_iterator(&aux_vect3[0]), detail::make_move_iterator(aux_vect3 + 50));
stdmultimap->insert(constant_beg, constant_end);
if(!CheckEqualPairContainers(shmmap, stdmap)) return 1;
if(!CheckEqualPairContainers(shmmultimap, stdmultimap)) return 1;
for(int i = 0, j = static_cast<int>(shmmap->size()); i < j; ++i){
shmmap->erase(IntType(i));
stdmap->erase(i);
shmmultimap->erase(IntType(i));
stdmultimap->erase(i);
}
if(!CheckEqualPairContainers(shmmap, stdmap)) return 1;
if(!CheckEqualPairContainers(shmmultimap, stdmultimap)) return 1;
}
{
IntPairType aux_vect[50];
for(int i = 0; i < 50; ++i){
new(&aux_vect[i])IntPairType(IntType(-1), IntType(-1));
}
typename MyShmMap::iterator it;
typename MyShmMap::const_iterator cit = it;
IntPairType aux_vect3[50];
for(int i = 0; i < 50; ++i){
new(&aux_vect3[i])IntPairType(IntType(-1), IntType(-1));
}
IntPairType aux_vect4[50];
for(int i = 0; i < 50; ++i){
new(&aux_vect4[i])IntPairType(IntType(-1), IntType(-1));
}
IntPairType aux_vect5[50];
for(int i = 0; i < 50; ++i){
new(&aux_vect5[i])IntPairType(IntType(-1), IntType(-1));
}
shmmap->insert(detail::make_move_iterator(&aux_vect[0]), detail::make_move_iterator(aux_vect + 50));
shmmap->insert(detail::make_move_iterator(&aux_vect3[0]), detail::make_move_iterator(aux_vect3 + 50));
StdPairType stdpairtype(-1, -1);
constant_iterator<StdPairType> constant_beg(stdpairtype, 50), constant_end;
stdmap->insert(constant_beg, constant_end);
stdmap->insert(constant_beg, constant_end);
shmmultimap->insert(detail::make_move_iterator(&aux_vect4[0]), detail::make_move_iterator(aux_vect4 + 50));
shmmultimap->insert(detail::make_move_iterator(&aux_vect5[0]), detail::make_move_iterator(aux_vect5 + 50));
stdmultimap->insert(constant_beg, constant_end);
stdmultimap->insert(constant_beg, constant_end);
shmmap->erase(shmmap->begin()++);
stdmap->erase(stdmap->begin()++);
shmmultimap->erase(shmmultimap->begin()++);
stdmultimap->erase(stdmultimap->begin()++);
if(!CheckEqualPairContainers(shmmap, stdmap)) return 1;
if(!CheckEqualPairContainers(shmmultimap, stdmultimap)) return 1;
shmmap->erase(shmmap->begin()->first);
stdmap->erase(stdmap->begin()->first);
shmmultimap->erase(shmmultimap->begin()->first);
stdmultimap->erase(stdmultimap->begin()->first);
shmmap->erase(shmmap->begin());
stdmap->erase(stdmap->begin());
shmmultimap->erase(shmmultimap->begin());
stdmultimap->erase(stdmultimap->begin());
if(!CheckEqualPairContainers(shmmap, stdmap)) return 1;
if(!CheckEqualPairContainers(shmmultimap, stdmultimap)) return 1;
}
for(i = 0; i < max; ++i){
shmmap->insert(move(IntPairType(move(IntType(i)), move(IntType(i)))));
stdmap->insert(StdPairType(i, i));
shmmultimap->insert(move(IntPairType(move(IntType(i)), move(IntType(i)))));
stdmultimap->insert(StdPairType(i, i));
}
//Swapping test
std::less<IntType> lessfunc;
MyShmMap tmpshmemap2 (lessfunc, segment.get_segment_manager());
MyStdMap tmpstdmap2;
MyShmMultiMap tmpshmemultimap2(lessfunc, segment.get_segment_manager());
MyStdMultiMap tmpstdmultimap2;
shmmap->swap(tmpshmemap2);
stdmap->swap(tmpstdmap2);
shmmultimap->swap(tmpshmemultimap2);
stdmultimap->swap(tmpstdmultimap2);
shmmap->swap(tmpshmemap2);
stdmap->swap(tmpstdmap2);
shmmultimap->swap(tmpshmemultimap2);
stdmultimap->swap(tmpstdmultimap2);
if(!CheckEqualPairContainers(shmmap, stdmap)) return 1;
if(!CheckEqualPairContainers(shmmultimap, stdmultimap)) return 1;
if(!CheckEqualPairContainers(shmmap, stdmap)) return 1;
if(!CheckEqualPairContainers(shmmultimap, stdmultimap)) return 1;
//Insertion from other container
//Initialize values
{
//This is really nasty, but we have no other simple choice
IntPairType aux_vect[50];
for(int i = 0; i < 50; ++i){
new(&aux_vect[i])IntPairType(IntType(-1), IntType(-1));
}
IntPairType aux_vect3[50];
for(int i = 0; i < 50; ++i){
new(&aux_vect3[i])IntPairType(IntType(-1), IntType(-1));
}
for(i = 0; i < max; ++i){
shmmap->insert(shmmap->begin(), move(IntPairType(move(IntType(i)), move(IntType(i)))));
stdmap->insert(stdmap->begin(), StdPairType(i, i));
//PrintContainers(shmmap, stdmap);
shmmultimap->insert(shmmultimap->begin(), move(IntPairType(move(IntType(i)), move(IntType(i)))));
stdmultimap->insert(stdmultimap->begin(), StdPairType(i, i));
//PrintContainers(shmmultimap, stdmultimap);
if(!CheckEqualPairContainers(shmmap, stdmap))
return 1;
if(!CheckEqualPairContainers(shmmultimap, stdmultimap))
return 1;
shmmap->insert(detail::make_move_iterator(&aux_vect[0]), detail::make_move_iterator(aux_vect + 50));
StdPairType stdpairtype(-1, -1);
constant_iterator<StdPairType> constant_beg(stdpairtype, 50), constant_end;
stdmap->insert(constant_beg, constant_end);
shmmultimap->insert(detail::make_move_iterator(&aux_vect3[0]), detail::make_move_iterator(aux_vect3 + 50));
stdmultimap->insert(constant_beg, constant_end);
if(!CheckEqualPairContainers(shmmap, stdmap)) return 1;
if(!CheckEqualPairContainers(shmmultimap, stdmultimap)) return 1;
shmmap->insert(shmmap->end(), move(IntPairType(move(IntType(i)), move(IntType(i)))));
stdmap->insert(stdmap->end(), StdPairType(i, i));
shmmultimap->insert(shmmultimap->end(), move(IntPairType(move(IntType(i)), move(IntType(i)))));
stdmultimap->insert(stdmultimap->end(), StdPairType(i, i));
if(!CheckEqualPairContainers(shmmap, stdmap))
return 1;
if(!CheckEqualPairContainers(shmmultimap, stdmultimap))
return 1;
for(int i = 0, j = static_cast<int>(shmmap->size()); i < j; ++i){
shmmap->erase(IntType(i));
stdmap->erase(i);
shmmultimap->erase(IntType(i));
stdmultimap->erase(i);
}
if(!CheckEqualPairContainers(shmmap, stdmap)) return 1;
if(!CheckEqualPairContainers(shmmultimap, stdmultimap)) return 1;
}
{
IntPairType aux_vect[50];
for(int i = 0; i < 50; ++i){
new(&aux_vect[i])IntPairType(IntType(-1), IntType(-1));
}
shmmap->insert(shmmap->lower_bound(IntType(i)), move(IntPairType(move(IntType(i)), move(IntType(i)))));
stdmap->insert(stdmap->lower_bound(i), StdPairType(i, i));
//PrintContainers(shmmap, stdmap);
shmmultimap->insert(shmmultimap->lower_bound(IntType(i)), move(IntPairType(move(IntType(i)), move(IntType(i)))));
stdmultimap->insert(stdmultimap->lower_bound(i), StdPairType(i, i));
//PrintContainers(shmmultimap, stdmultimap);
if(!CheckEqualPairContainers(shmmap, stdmap))
return 1;
if(!CheckEqualPairContainers(shmmultimap, stdmultimap))
return 1;
shmmap->insert(shmmap->upper_bound(IntType(i)), move(IntPairType(move(IntType(i)), move(IntType(i)))));
stdmap->insert(stdmap->upper_bound(i), StdPairType(i, i));
//PrintContainers(shmmap, stdmap);
shmmultimap->insert(shmmultimap->upper_bound(IntType(i)), move(IntPairType(move(IntType(i)), move(IntType(i)))));
stdmultimap->insert(stdmultimap->upper_bound(i), StdPairType(i, i));
//PrintContainers(shmmultimap, stdmultimap);
if(!CheckEqualPairContainers(shmmap, stdmap))
return 1;
if(!CheckEqualPairContainers(shmmultimap, stdmultimap))
return 1;
}
IntPairType aux_vect3[50];
for(int i = 0; i < 50; ++i){
new(&aux_vect3[i])IntPairType(IntType(-1), IntType(-1));
}
//Compare count with std containers
for(i = 0; i < max; ++i){
if(shmmap->count(IntType(i)) != stdmap->count(i)){
return -1;
IntPairType aux_vect4[50];
for(int i = 0; i < 50; ++i){
new(&aux_vect4[i])IntPairType(IntType(-1), IntType(-1));
}
IntPairType aux_vect5[50];
for(int i = 0; i < 50; ++i){
new(&aux_vect5[i])IntPairType(IntType(-1), IntType(-1));
}
shmmap->insert(detail::make_move_iterator(&aux_vect[0]), detail::make_move_iterator(aux_vect + 50));
shmmap->insert(detail::make_move_iterator(&aux_vect3[0]), detail::make_move_iterator(aux_vect3 + 50));
StdPairType stdpairtype(-1, -1);
constant_iterator<StdPairType> constant_beg(stdpairtype, 50), constant_end;
stdmap->insert(constant_beg, constant_end);
stdmap->insert(constant_beg, constant_end);
shmmultimap->insert(detail::make_move_iterator(&aux_vect4[0]), detail::make_move_iterator(aux_vect4 + 50));
shmmultimap->insert(detail::make_move_iterator(&aux_vect5[0]), detail::make_move_iterator(aux_vect5 + 50));
stdmultimap->insert(constant_beg, constant_end);
stdmultimap->insert(constant_beg, constant_end);
if(!CheckEqualPairContainers(shmmap, stdmap)) return 1;
if(!CheckEqualPairContainers(shmmultimap, stdmultimap)) return 1;
shmmap->erase(shmmap->begin()->first);
stdmap->erase(stdmap->begin()->first);
shmmultimap->erase(shmmultimap->begin()->first);
stdmultimap->erase(stdmultimap->begin()->first);
if(!CheckEqualPairContainers(shmmap, stdmap)) return 1;
if(!CheckEqualPairContainers(shmmultimap, stdmultimap)) return 1;
}
if(shmmultimap->count(IntType(i)) != stdmultimap->count(i)){
return -1;
for(i = 0; i < max; ++i){
shmmap->insert(move(IntPairType(move(IntType(i)), move(IntType(i)))));
stdmap->insert(StdPairType(i, i));
shmmultimap->insert(move(IntPairType(move(IntType(i)), move(IntType(i)))));
stdmultimap->insert(StdPairType(i, i));
}
}
//Now do count exercise
shmmap->clear();
shmmultimap->clear();
if(!CheckEqualPairContainers(shmmap, stdmap)) return 1;
if(!CheckEqualPairContainers(shmmultimap, stdmultimap)) return 1;
for(j = 0; j < 3; ++j)
for(i = 0; i < 100; ++i){
shmmap->insert(move(IntPairType(move(IntType(i)), move(IntType(i)))));
shmmultimap->insert(move(IntPairType(move(IntType(i)), move(IntType(i)))));
if(shmmap->count(IntType(i)) != typename MyShmMultiMap::size_type(1))
for(i = 0; i < max; ++i){
shmmap->insert(shmmap->begin(), move(IntPairType(move(IntType(i)), move(IntType(i)))));
stdmap->insert(stdmap->begin(), StdPairType(i, i));
//PrintContainers(shmmap, stdmap);
shmmultimap->insert(shmmultimap->begin(), move(IntPairType(move(IntType(i)), move(IntType(i)))));
stdmultimap->insert(stdmultimap->begin(), StdPairType(i, i));
//PrintContainers(shmmultimap, stdmultimap);
if(!CheckEqualPairContainers(shmmap, stdmap))
return 1;
if(!CheckEqualPairContainers(shmmultimap, stdmultimap))
return 1;
shmmap->insert(shmmap->end(), move(IntPairType(move(IntType(i)), move(IntType(i)))));
stdmap->insert(stdmap->end(), StdPairType(i, i));
shmmultimap->insert(shmmultimap->end(), move(IntPairType(move(IntType(i)), move(IntType(i)))));
stdmultimap->insert(stdmultimap->end(), StdPairType(i, i));
if(!CheckEqualPairContainers(shmmap, stdmap))
return 1;
if(!CheckEqualPairContainers(shmmultimap, stdmultimap))
return 1;
shmmap->insert(shmmap->lower_bound(IntType(i)), move(IntPairType(move(IntType(i)), move(IntType(i)))));
stdmap->insert(stdmap->lower_bound(i), StdPairType(i, i));
//PrintContainers(shmmap, stdmap);
shmmultimap->insert(shmmultimap->lower_bound(IntType(i)), move(IntPairType(move(IntType(i)), move(IntType(i)))));
stdmultimap->insert(stdmultimap->lower_bound(i), StdPairType(i, i));
//PrintContainers(shmmultimap, stdmultimap);
if(!CheckEqualPairContainers(shmmap, stdmap))
return 1;
if(!CheckEqualPairContainers(shmmultimap, stdmultimap))
return 1;
shmmap->insert(shmmap->upper_bound(IntType(i)), move(IntPairType(move(IntType(i)), move(IntType(i)))));
stdmap->insert(stdmap->upper_bound(i), StdPairType(i, i));
//PrintContainers(shmmap, stdmap);
shmmultimap->insert(shmmultimap->upper_bound(IntType(i)), move(IntPairType(move(IntType(i)), move(IntType(i)))));
stdmultimap->insert(stdmultimap->upper_bound(i), StdPairType(i, i));
//PrintContainers(shmmultimap, stdmultimap);
if(!CheckEqualPairContainers(shmmap, stdmap))
return 1;
if(!CheckEqualPairContainers(shmmultimap, stdmultimap))
return 1;
}
//Compare count with std containers
for(i = 0; i < max; ++i){
if(shmmap->count(IntType(i)) != stdmap->count(i)){
return -1;
}
if(shmmultimap->count(IntType(i)) != stdmultimap->count(i)){
return -1;
}
}
//Now do count exercise
shmmap->clear();
shmmultimap->clear();
for(j = 0; j < 3; ++j)
for(i = 0; i < 100; ++i){
shmmap->insert(move(IntPairType(move(IntType(i)), move(IntType(i)))));
shmmultimap->insert(move(IntPairType(move(IntType(i)), move(IntType(i)))));
if(shmmap->count(IntType(i)) != typename MyShmMultiMap::size_type(1))
return 1;
if(shmmultimap->count(IntType(i)) != typename MyShmMultiMap::size_type(j+1))
return 1;
}
segment.template destroy<MyShmMap>("MyShmMap");
delete stdmap;
segment.destroy_ptr(shmmultimap);
delete stdmultimap;
segment.shrink_to_fit_indexes();
if(!segment.all_memory_deallocated())
return 1;
if(shmmultimap->count(IntType(i)) != typename MyShmMultiMap::size_type(j+1))
return 1;
}
segment.template destroy<MyShmMap>("MyShmMap");
delete stdmap;
segment.destroy_ptr(shmmultimap);
delete stdmultimap;
}
catch(...){
shared_memory_object::remove(shMemName);
@@ -331,7 +338,7 @@ int map_test_copyable ()
typedef typename MyStdMap::value_type StdPairType;
const int memsize = 65536;
const char *const shMemName = "/MySharedMemory";
const char *const shMemName = test::get_compiler_name();
const int max = 100;
try{
@@ -365,29 +372,35 @@ int map_test_copyable ()
if(!CheckEqualContainers(shmmap, stdmap)) return 1;
if(!CheckEqualContainers(shmmultimap, stdmultimap)) return 1;
{
//Now, test copy constructor
MyShmMap shmmapcopy(*shmmap);
MyStdMap stdmapcopy(*stdmap);
MyShmMultiMap shmmmapcopy(*shmmultimap);
MyStdMultiMap stdmmapcopy(*stdmultimap);
{
//Now, test copy constructor
MyShmMap shmmapcopy(*shmmap);
MyStdMap stdmapcopy(*stdmap);
MyShmMultiMap shmmmapcopy(*shmmultimap);
MyStdMultiMap stdmmapcopy(*stdmultimap);
if(!CheckEqualContainers(&shmmapcopy, &stdmapcopy))
return 1;
if(!CheckEqualContainers(&shmmmapcopy, &stdmmapcopy))
return 1;
if(!CheckEqualContainers(&shmmapcopy, &stdmapcopy))
return 1;
if(!CheckEqualContainers(&shmmmapcopy, &stdmmapcopy))
return 1;
//And now assignment
shmmapcopy = *shmmap;
stdmapcopy = *stdmap;
shmmmapcopy = *shmmultimap;
stdmmapcopy = *stdmultimap;
if(!CheckEqualContainers(&shmmapcopy, &stdmapcopy))
//And now assignment
shmmapcopy = *shmmap;
stdmapcopy = *stdmap;
shmmmapcopy = *shmmultimap;
stdmmapcopy = *stdmultimap;
if(!CheckEqualContainers(&shmmapcopy, &stdmapcopy))
return 1;
if(!CheckEqualContainers(&shmmmapcopy, &stdmmapcopy))
return 1;
segment.destroy_ptr(shmmap);
segment.destroy_ptr(shmmultimap);
}
segment.shrink_to_fit_indexes();
if(!segment.all_memory_deallocated())
return 1;
if(!CheckEqualContainers(&shmmmapcopy, &stdmmapcopy))
return 1;
}
}
catch(...){
shared_memory_object::remove(shMemName);

View File

@@ -16,9 +16,13 @@
#include "named_creation_template.hpp"
#include <cstdio>
#include <cstring>
#include <string>
#include "get_compiler_name.hpp"
using namespace boost::interprocess;
static const std::size_t FileSize = 1000;
static const char * FileName = "mapped_file";
static const char * FileName = test::get_compiler_name();
struct file_destroyer
{
@@ -39,22 +43,21 @@ class mapped_file_creation_test_wrapper
typedef boost::interprocess::detail::managed_open_or_create_impl
<boost::interprocess::detail::file_wrapper> mapped_file;
public:
mapped_file_creation_test_wrapper(boost::interprocess::detail::create_only_t)
mapped_file_creation_test_wrapper(boost::interprocess::create_only_t)
: mapped_file(boost::interprocess::create_only, FileName, FileSize)
{}
mapped_file_creation_test_wrapper(boost::interprocess::detail::open_only_t)
mapped_file_creation_test_wrapper(boost::interprocess::open_only_t)
: mapped_file(boost::interprocess::open_only, FileName)
{}
mapped_file_creation_test_wrapper(boost::interprocess::detail::open_or_create_t)
mapped_file_creation_test_wrapper(boost::interprocess::open_or_create_t)
: mapped_file(boost::interprocess::open_or_create, FileName, FileSize)
{}
};
int main ()
{
using namespace boost::interprocess;
typedef boost::interprocess::detail::managed_open_or_create_impl
<boost::interprocess::detail::file_wrapper> mapped_file;
std::remove(FileName);

View File

@@ -16,13 +16,14 @@
#include <boost/interprocess/sync/mutex_family.hpp>
#include "memory_algorithm_test_template.hpp"
#include <iostream>
#include <string>
#include "get_compiler_name.hpp"
int main ()
{
using namespace boost::interprocess;
const int memsize = 16384;
const char *const shMemName = "MySharedMemory";
const char *const shMemName = test::get_compiler_name();
{
//A shared memory with simple sequential fit algorithm

View File

@@ -114,8 +114,9 @@ bool test_allocation_shrink(Allocator &a)
;i < max
; ++i){
std::size_t received_size;
if(a.allocation_command( shrink_in_place | nothrow_allocation, i*2
, i, received_size, buffers[i]).first){
if(a.template allocation_command<char>
( shrink_in_place | nothrow_allocation, i*2
, i, received_size, (char*)buffers[i]).first){
if(received_size > std::size_t(i*2)){
return false;
}
@@ -162,8 +163,9 @@ bool test_allocation_expand(Allocator &a)
std::size_t preferred_size = i*2;
preferred_size = min_size > preferred_size ? min_size : preferred_size;
while(a.allocation_command( expand_fwd | nothrow_allocation, min_size
, preferred_size, received_size, buffers[i]).first){
while(a.template allocation_command<char>
( expand_fwd | nothrow_allocation, min_size
, preferred_size, received_size, (char*)buffers[i]).first){
//Check received size is bigger than minimum
if(received_size < min_size){
return false;
@@ -199,13 +201,11 @@ bool test_allocation_shrink_and_expand(Allocator &a)
//Allocate buffers wand store received sizes
for(int i = 0; true; ++i){
std::size_t received_size;
void *ptr = a.allocation_command
( allocate_new | nothrow_allocation, i
, i*2, received_size).first;
void *ptr = a.template allocation_command<char>
( allocate_new | nothrow_allocation, i, i*2, received_size).first;
if(!ptr){
ptr = a.allocation_command
( allocate_new | nothrow_allocation, 1
, i*2, received_size).first;
ptr = a.template allocation_command<char>
( allocate_new | nothrow_allocation, 1, i*2, received_size).first;
if(!ptr)
break;
}
@@ -218,8 +218,9 @@ bool test_allocation_shrink_and_expand(Allocator &a)
;i < max
; ++i){
std::size_t received_size;
if(a.allocation_command( shrink_in_place | nothrow_allocation, received_sizes[i]
, i, received_size, buffers[i]).first){
if(a.template allocation_command<char>
( shrink_in_place | nothrow_allocation, received_sizes[i]
, i, received_size, (char*)buffers[i]).first){
if(received_size > std::size_t(received_sizes[i])){
return false;
}
@@ -235,9 +236,9 @@ bool test_allocation_shrink_and_expand(Allocator &a)
;i < max
;++i){
std::size_t received_size;
if(a.allocation_command( expand_fwd | nothrow_allocation, received_sizes[i]
, received_sizes[i], received_size, buffers[i]).first){
if(a.template allocation_command<char>
( expand_fwd | nothrow_allocation, received_sizes[i]
, received_sizes[i], received_size, (char*)buffers[i]).first){
if(received_size != received_sizes[i]){
return false;
}
@@ -298,8 +299,9 @@ bool test_allocation_deallocation_expand(Allocator &a)
std::size_t preferred_size = i*2;
preferred_size = min_size > preferred_size ? min_size : preferred_size;
while(a.allocation_command( expand_fwd | nothrow_allocation, min_size
, preferred_size, received_size, buffers[i]).first){
while(a.template allocation_command<char>
( expand_fwd | nothrow_allocation, min_size
, preferred_size, received_size, (char*)buffers[i]).first){
//Check received size is bigger than minimum
if(received_size < min_size){
return false;
@@ -363,9 +365,9 @@ bool test_allocation_with_reuse(Allocator &a)
//Now allocate with reuse
std::size_t received_size = 0;
for(int i = 0; true; ++i){
std::pair<void*, bool> ret =
a.allocation_command( expand_bwd | nothrow_allocation, received_size/size*size + size
, received_size/size*size+(i+1)*size*2, received_size, ptr, size);
std::pair<void*, bool> ret = a.template allocation_command<char>
( expand_bwd | nothrow_allocation, received_size/size*size + size
, received_size/size*size+(i+1)*size*2, received_size, (char*)ptr);
if(!ret.first)
break;
//If we have memory, this must be a buffer reuse
@@ -519,6 +521,199 @@ bool test_clear_free_memory(Allocator &a)
return true;
}
//This test allocates multiple values until there is no more memory
//and after that deallocates all in the inverse order
template<class Allocator>
bool test_many_equal_allocation_inverse_deallocation(Allocator &a)
{
typedef typename Allocator::multiallocation_iterator multiallocation_iterator;
std::vector<void*> buffers;
for(int i = 0; true; ++i){
std::size_t received_size;
multiallocation_iterator it = a.allocate_many(i+1, i+1, (i+1)*2, received_size, std::nothrow);
if(!it)
break;
multiallocation_iterator itend;
for(; it != itend; ++it){
buffers.push_back(*it);
}
}
for(int j = (int)buffers.size()
;j--
;){
a.deallocate(buffers[j]);
}
return a.all_memory_deallocated() && a.check_sanity();
}
//This test allocates multiple values until there is no more memory
//and after that deallocates all in the same order
template<class Allocator>
bool test_many_equal_allocation_direct_deallocation(Allocator &a)
{
typedef typename Allocator::multiallocation_iterator multiallocation_iterator;
std::vector<void*> buffers;
std::size_t free_memory = a.get_free_memory();
for(int i = 0; true; ++i){
std::size_t received_size;
multiallocation_iterator it = a.allocate_many(i+1, i+1, (i+1)*2, received_size, std::nothrow);
if(!it)
break;
multiallocation_iterator itend;
for(; it != itend; ++it){
buffers.push_back(*it);
}
}
for(int j = 0, max = (int)buffers.size()
;j < max
;++j){
a.deallocate(buffers[j]);
}
return free_memory == a.get_free_memory() &&
a.all_memory_deallocated() && a.check_sanity();
}
//This test allocates multiple values until there is no more memory
//and after that deallocates all following a pattern
template<class Allocator>
bool test_many_equal_allocation_mixed_deallocation(Allocator &a)
{
typedef typename Allocator::multiallocation_iterator multiallocation_iterator;
std::vector<void*> buffers;
for(int i = 0; true; ++i){
std::size_t received_size;
multiallocation_iterator it = a.allocate_many(i+1, i+1, (i+1)*2, received_size, std::nothrow);
if(!it)
break;
multiallocation_iterator itend;
for(; it != itend; ++it){
buffers.push_back(*it);
}
}
for(int j = 0, max = (int)buffers.size()
;j < max
;++j){
int pos = (j%4)*((int)buffers.size())/4;
a.deallocate(buffers[pos]);
buffers.erase(buffers.begin()+pos);
}
return a.all_memory_deallocated() && a.check_sanity();
}
//This test allocates multiple values until there is no more memory
//and after that deallocates all in the inverse order
template<class Allocator>
bool test_many_different_allocation_inverse_deallocation(Allocator &a)
{
typedef typename Allocator::multiallocation_iterator multiallocation_iterator;
const std::size_t ArraySize = 11;
std::size_t requested_sizes[ArraySize];
for(std::size_t i = 0; i < ArraySize; ++i){
requested_sizes[i] = 4*i;
}
std::vector<void*> buffers;
for(int i = 0; true; ++i){
multiallocation_iterator it = a.allocate_many(requested_sizes, ArraySize, 1, std::nothrow);
if(!it)
break;
multiallocation_iterator itend;
for(; it != itend; ++it){
buffers.push_back(*it);
}
}
for(int j = (int)buffers.size()
;j--
;){
a.deallocate(buffers[j]);
}
return a.all_memory_deallocated() && a.check_sanity();
}
//This test allocates multiple values until there is no more memory
//and after that deallocates all in the same order
template<class Allocator>
bool test_many_different_allocation_direct_deallocation(Allocator &a)
{
std::size_t free_memory = a.get_free_memory();
typedef typename Allocator::multiallocation_iterator multiallocation_iterator;
const std::size_t ArraySize = 11;
std::size_t requested_sizes[ArraySize];
for(std::size_t i = 0; i < ArraySize; ++i){
requested_sizes[i] = 4*i;
}
std::vector<void*> buffers;
for(int i = 0; true; ++i){
multiallocation_iterator it = a.allocate_many(requested_sizes, ArraySize, 1, std::nothrow);
if(!it)
break;
multiallocation_iterator itend;
for(; it != itend; ++it){
buffers.push_back(*it);
}
}
for(int j = 0, max = (int)buffers.size()
;j < max
;++j){
a.deallocate(buffers[j]);
}
return free_memory == a.get_free_memory() &&
a.all_memory_deallocated() && a.check_sanity();
}
//This test allocates multiple values until there is no more memory
//and after that deallocates all following a pattern
template<class Allocator>
bool test_many_different_allocation_mixed_deallocation(Allocator &a)
{
typedef typename Allocator::multiallocation_iterator multiallocation_iterator;
const std::size_t ArraySize = 11;
std::size_t requested_sizes[ArraySize];
for(std::size_t i = 0; i < ArraySize; ++i){
requested_sizes[i] = 4*i;
}
std::vector<void*> buffers;
for(int i = 0; true; ++i){
multiallocation_iterator it = a.allocate_many(requested_sizes, ArraySize, 1, std::nothrow);
if(!it)
break;
multiallocation_iterator itend;
for(; it != itend; ++it){
buffers.push_back(*it);
}
}
for(int j = 0, max = (int)buffers.size()
;j < max
;++j){
int pos = (j%4)*((int)buffers.size())/4;
a.deallocate(buffers[pos]);
buffers.erase(buffers.begin()+pos);
}
return a.all_memory_deallocated() && a.check_sanity();
}
//This function calls all tests
template<class Allocator>
@@ -551,6 +746,60 @@ bool test_all_allocation(Allocator &a)
return false;
}
std::cout << "Starting test_many_equal_allocation_direct_deallocation. Class: "
<< typeid(a).name() << std::endl;
if(!test_many_equal_allocation_direct_deallocation(a)){
std::cout << "test_many_equal_allocation_direct_deallocation failed. Class: "
<< typeid(a).name() << std::endl;
return false;
}
std::cout << "Starting test_many_equal_allocation_inverse_deallocation. Class: "
<< typeid(a).name() << std::endl;
if(!test_many_equal_allocation_inverse_deallocation(a)){
std::cout << "test_many_equal_allocation_inverse_deallocation failed. Class: "
<< typeid(a).name() << std::endl;
return false;
}
std::cout << "Starting test_many_equal_allocation_mixed_deallocation. Class: "
<< typeid(a).name() << std::endl;
if(!test_many_equal_allocation_mixed_deallocation(a)){
std::cout << "test_many_equal_allocation_mixed_deallocation failed. Class: "
<< typeid(a).name() << std::endl;
return false;
}
std::cout << "Starting test_many_different_allocation_direct_deallocation. Class: "
<< typeid(a).name() << std::endl;
if(!test_many_different_allocation_direct_deallocation(a)){
std::cout << "test_many_different_allocation_direct_deallocation failed. Class: "
<< typeid(a).name() << std::endl;
return false;
}
std::cout << "Starting test_many_different_allocation_inverse_deallocation. Class: "
<< typeid(a).name() << std::endl;
if(!test_many_different_allocation_inverse_deallocation(a)){
std::cout << "test_many_different_allocation_inverse_deallocation failed. Class: "
<< typeid(a).name() << std::endl;
return false;
}
std::cout << "Starting test_many_different_allocation_mixed_deallocation. Class: "
<< typeid(a).name() << std::endl;
if(!test_many_different_allocation_mixed_deallocation(a)){
std::cout << "test_many_different_allocation_mixed_deallocation failed. Class: "
<< typeid(a).name() << std::endl;
return false;
}
std::cout << "Starting test_allocation_shrink. Class: "
<< typeid(a).name() << std::endl;

View File

@@ -20,6 +20,8 @@
#include <limits>
#include <boost/thread.hpp>
#include <memory>
#include <string>
#include "get_compiler_name.hpp"
#ifdef max
#undef max
@@ -38,12 +40,12 @@ using namespace boost::interprocess;
//messages with same priority are received in fifo order
bool test_priority_order()
{
message_queue::remove("test_priority_order");
message_queue::remove(test::get_compiler_name());
{
message_queue mq1
(open_or_create, "test_priority_order", 100, sizeof(std::size_t)),
(open_or_create, test::get_compiler_name(), 100, sizeof(std::size_t)),
mq2
(open_or_create, "test_priority_order", 100, sizeof(std::size_t));
(open_or_create, test::get_compiler_name(), 100, sizeof(std::size_t));
//We test that the queue is ordered by priority and in the
//same priority, is a FIFO
@@ -75,7 +77,7 @@ bool test_priority_order()
tstamp_prev = tstamp;
}
}
message_queue::remove("test_priority_order");
message_queue::remove(test::get_compiler_name());
return true;
}
@@ -103,13 +105,13 @@ bool test_serialize_db()
//Allocate a memory buffer to hold the destiny database using vector<char>
std::vector<char> buffer_destiny(BufferSize, 0);
message_queue::remove("message_queue");
message_queue::remove(test::get_compiler_name());
{
//Create the message-queues
message_queue mq1(create_only, "message_queue", 1, MaxMsgSize);
message_queue mq1(create_only, test::get_compiler_name(), 1, MaxMsgSize);
//Open previously created message-queue simulating other process
message_queue mq2(open_only, "message_queue");
message_queue mq2(open_only, test::get_compiler_name());
//A managed heap memory to create the origin database
managed_heap_memory db_origin(buffer_destiny.size());
@@ -194,7 +196,7 @@ bool test_serialize_db()
db_origin.destroy_ptr(map1);
db_destiny.destroy_ptr(map2);
}
message_queue::remove("message_queue");
message_queue::remove(test::get_compiler_name());
return true;
}
//]
@@ -219,11 +221,11 @@ void receiver()
bool test_buffer_overflow()
{
boost::interprocess::message_queue::remove("mymsg");
boost::interprocess::message_queue::remove(test::get_compiler_name());
{
std::auto_ptr<boost::interprocess::message_queue>
ptr(new boost::interprocess::message_queue
(create_only, "mymsg", 10, 10));
(create_only, test::get_compiler_name(), 10, 10));
pmessage_queue = ptr.get();
//Launch the receiver thread
@@ -238,7 +240,7 @@ bool test_buffer_overflow()
thread.join();
}
boost::interprocess::message_queue::remove("mymsg");
boost::interprocess::message_queue::remove(test::get_compiler_name());
return true;
}

View File

@@ -24,6 +24,7 @@
#include <iterator>
#include <set>
#include <string>
#include "get_compiler_name.hpp"
namespace boost { namespace interprocess { namespace test {
@@ -49,19 +50,19 @@ bool test_names_and_types(ManagedMemory &m)
if(!ptr)
break;
std::size_t namelen = char_traits_type::length(m.get_name(ptr));
std::size_t namelen = char_traits_type::length(m.get_instance_name(ptr));
if(namelen != char_traits_type::length(name)){
return 1;
}
if(char_traits_type::compare(m.get_name(ptr), name, namelen) != 0){
if(char_traits_type::compare(m.get_instance_name(ptr), name, namelen) != 0){
return 1;
}
if(m.template find<char>(name).first == 0)
return false;
if(m.get_type(ptr) != detail::named_type)
if(m.get_instance_type(ptr) != named_type)
return false;
buffers.push_back(ptr);
@@ -78,6 +79,9 @@ bool test_names_and_types(ManagedMemory &m)
if(m.get_num_named_objects() != 0 || !m.check_sanity())
return false;
m.shrink_to_fit_indexes();
if(!m.all_memory_deallocated())
return false;
return true;
}
@@ -148,6 +152,51 @@ bool test_named_iterators(ManagedMemory &m)
if(m.get_num_named_objects() != 0 || !m.check_sanity())
return false;
m.shrink_to_fit_indexes();
if(!m.all_memory_deallocated())
return false;
return true;
}
//This test allocates until there is no more memory
//and after that deallocates all in the same order
template<class ManagedMemory>
bool test_shrink_to_fit(ManagedMemory &m)
{
typedef typename ManagedMemory::char_type char_type;
typedef std::char_traits<char_type> char_traits_type;
std::vector<char*> buffers;
const int BufferLen = 100;
char_type name[BufferLen];
basic_bufferstream<char_type> formatter(name, BufferLen);
std::size_t free_memory_before = m.get_free_memory();
for(int i = 0; true; ++i){
formatter.seekp(0);
formatter << "prefix_name_" << i << std::ends;
char *ptr = m.template construct<char>(name, std::nothrow)(i);
if(!ptr)
break;
buffers.push_back(ptr);
}
for(int j = 0, max = (int)buffers.size()
;j < max
;++j){
m.destroy_ptr(buffers[j]);
}
std::size_t free_memory_after = m.get_free_memory();
if(free_memory_before != free_memory_after){
m.shrink_to_fit_indexes();
if(free_memory_before != free_memory_after)
return false;
}
return true;
}
@@ -186,6 +235,9 @@ bool test_direct_named_allocation_destruction(ManagedMemory &m)
if(m.get_num_named_objects() != 0 || !m.check_sanity())
return false;
m.shrink_to_fit_indexes();
if(!m.all_memory_deallocated())
return false;
return true;
}
@@ -223,6 +275,9 @@ bool test_named_allocation_inverse_destruction(ManagedMemory &m)
if(m.get_num_named_objects() != 0 || !m.check_sanity())
return false;
m.shrink_to_fit_indexes();
if(!m.all_memory_deallocated())
return false;
return true;
}
@@ -262,6 +317,9 @@ bool test_named_allocation_mixed_destruction(ManagedMemory &m)
if(m.get_num_named_objects() != 0 || !m.check_sanity())
return false;
m.shrink_to_fit_indexes();
if(!m.all_memory_deallocated())
return false;
return true;
}
@@ -299,6 +357,9 @@ bool test_inverse_named_allocation_destruction(ManagedMemory &m)
if(m.get_num_named_objects() != 0 || !m.check_sanity())
return false;
m.shrink_to_fit_indexes();
if(!m.all_memory_deallocated())
return false;
return true;
}
@@ -366,7 +427,7 @@ bool test_named_allocation()
{
using namespace boost::interprocess;
const int memsize = 163840;
const char *const shMemName = "MySharedMemory";
const char *const shMemName = test::get_compiler_name();
try
{
//A shared memory with rbtree best fit algorithm

View File

@@ -16,6 +16,10 @@
#include <boost/lexical_cast.hpp>
#include "condition_test_template.hpp"
#include "named_creation_template.hpp"
#include <string>
#include "get_compiler_name.hpp"
using namespace boost::interprocess;
struct condition_deleter
{
@@ -24,25 +28,24 @@ struct condition_deleter
~condition_deleter()
{
if(name.empty())
boost::interprocess::named_condition::remove("named_condition");
named_condition::remove(test::add_to_compiler_name("named_condition"));
else
boost::interprocess::named_condition::remove(name.c_str());
named_condition::remove(name.c_str());
}
};
//This wrapper is necessary to have a default constructor
//in generic mutex_test_template functions
class named_condition_test_wrapper
: public condition_deleter, public boost::interprocess::named_condition
: public condition_deleter, public named_condition
{
public:
named_condition_test_wrapper()
: boost::interprocess::named_condition
(boost::interprocess::open_or_create,
("test_cond" + boost::lexical_cast<std::string>(count)).c_str())
: named_condition(open_or_create,
(test::add_to_compiler_name("test_cond") + boost::lexical_cast<std::string>(count)).c_str())
{
condition_deleter::name += "test_cond";
condition_deleter::name += test::add_to_compiler_name("test_cond");
condition_deleter::name += boost::lexical_cast<std::string>(count);
++count;
}
@@ -58,22 +61,19 @@ int named_condition_test_wrapper::count = 0;
//This wrapper is necessary to have a common constructor
//in generic named_creation_template functions
class named_condition_creation_test_wrapper
: public condition_deleter, public boost::interprocess::named_condition
: public condition_deleter, public named_condition
{
public:
named_condition_creation_test_wrapper(boost::interprocess::detail::create_only_t)
: boost::interprocess::named_condition
(boost::interprocess::create_only, "named_condition")
named_condition_creation_test_wrapper(create_only_t)
: named_condition(create_only, test::add_to_compiler_name("named_condition"))
{}
named_condition_creation_test_wrapper(boost::interprocess::detail::open_only_t)
: boost::interprocess::named_condition
(boost::interprocess::open_only, "named_condition")
named_condition_creation_test_wrapper(open_only_t)
: named_condition(open_only, test::add_to_compiler_name("named_condition"))
{}
named_condition_creation_test_wrapper(boost::interprocess::detail::open_or_create_t)
: boost::interprocess::named_condition
(boost::interprocess::open_or_create, "named_condition")
named_condition_creation_test_wrapper(open_or_create_t)
: named_condition(open_or_create, test::add_to_compiler_name("named_condition"))
{}
};
@@ -84,24 +84,23 @@ struct mutex_deleter
~mutex_deleter()
{
if(name.empty())
boost::interprocess::named_mutex::remove("named_mutex");
named_mutex::remove(test::add_to_compiler_name("named_mutex"));
else
boost::interprocess::named_mutex::remove(name.c_str());
named_mutex::remove(name.c_str());
}
};
//This wrapper is necessary to have a default constructor
//in generic mutex_test_template functions
class named_mutex_test_wrapper
: public mutex_deleter, public boost::interprocess::named_mutex
: public mutex_deleter, public named_mutex
{
public:
named_mutex_test_wrapper()
: boost::interprocess::named_mutex
(boost::interprocess::open_or_create,
("test_mutex" + boost::lexical_cast<std::string>(count)).c_str())
: named_mutex(open_or_create,
(test::add_to_compiler_name("test_mutex") + boost::lexical_cast<std::string>(count)).c_str())
{
mutex_deleter::name += "test_mutex";
mutex_deleter::name += test::add_to_compiler_name("test_mutex");
mutex_deleter::name += boost::lexical_cast<std::string>(count);
++count;
}
@@ -116,14 +115,13 @@ int named_mutex_test_wrapper::count = 0;
int main ()
{
using namespace boost::interprocess;
try{
//Remove previous mutexes and conditions
named_mutex::remove("test_mutex0");
named_condition::remove("test_cond0");
named_condition::remove("test_cond1");
named_condition::remove("named_condition");
named_mutex::remove("named_mutex");
named_mutex::remove(test::add_to_compiler_name("test_mutex0"));
named_condition::remove(test::add_to_compiler_name("test_cond0"));
named_condition::remove(test::add_to_compiler_name("test_cond1"));
named_condition::remove(test::add_to_compiler_name("named_condition"));
named_mutex::remove(test::add_to_compiler_name("named_mutex"));
test::test_named_creation<named_condition_creation_test_wrapper>();
test::do_test_condition<named_condition_test_wrapper
@@ -133,11 +131,11 @@ int main ()
std::cout << ex.what() << std::endl;
return 1;
}
named_mutex::remove("test_mutex0");
named_condition::remove("test_cond0");
named_condition::remove("test_cond1");
named_condition::remove("named_condition");
named_mutex::remove("named_mutex");
named_mutex::remove(test::add_to_compiler_name("test_mutex0"));
named_condition::remove(test::add_to_compiler_name("test_cond0"));
named_condition::remove(test::add_to_compiler_name("test_cond1"));
named_condition::remove(test::add_to_compiler_name("named_condition"));
named_mutex::remove(test::add_to_compiler_name("named_mutex"));
return 0;
}

View File

@@ -15,7 +15,7 @@
#include <boost/interprocess/exceptions.hpp>
#include "boost_interprocess_check.hpp"
#include <iostream>
#include <boost/interprocess/detail/creation_tags.hpp>
#include <boost/interprocess/creation_tags.hpp>
namespace boost { namespace interprocess { namespace test {

View File

@@ -13,62 +13,61 @@
#include <boost/interprocess/sync/scoped_lock.hpp>
#include "mutex_test_template.hpp"
#include "named_creation_template.hpp"
#include <string>
#include "get_compiler_name.hpp"
struct deleter
using namespace boost::interprocess;
struct mutex_deleter
{
~deleter()
{ boost::interprocess::named_mutex::remove("named_mutex"); }
~mutex_deleter()
{ named_mutex::remove(test::get_compiler_name()); }
};
//This wrapper is necessary to have a default constructor
//in generic mutex_test_template functions
class named_mutex_lock_test_wrapper
: public boost::interprocess::named_mutex
: public named_mutex
{
public:
named_mutex_lock_test_wrapper()
: boost::interprocess::named_mutex
(boost::interprocess::open_or_create, "named_mutex")
: named_mutex(open_or_create, test::get_compiler_name())
{}
};
//This wrapper is necessary to have a common constructor
//in generic named_creation_template functions
class named_mutex_creation_test_wrapper
: public deleter, public boost::interprocess::named_mutex
: public mutex_deleter, public named_mutex
{
public:
named_mutex_creation_test_wrapper(boost::interprocess::detail::create_only_t)
: boost::interprocess::named_mutex
(boost::interprocess::create_only, "named_mutex")
named_mutex_creation_test_wrapper(create_only_t)
: named_mutex(create_only, test::get_compiler_name())
{}
named_mutex_creation_test_wrapper(boost::interprocess::detail::open_only_t)
: boost::interprocess::named_mutex
(boost::interprocess::open_only, "named_mutex")
named_mutex_creation_test_wrapper(open_only_t)
: named_mutex(open_only, test::get_compiler_name())
{}
named_mutex_creation_test_wrapper(boost::interprocess::detail::open_or_create_t)
: boost::interprocess::named_mutex
(boost::interprocess::open_or_create, "named_mutex")
named_mutex_creation_test_wrapper(open_or_create_t)
: named_mutex(open_or_create, test::get_compiler_name())
{}
};
int main ()
{
using namespace boost::interprocess;
try{
named_mutex::remove("named_mutex");
named_mutex::remove(test::get_compiler_name());
test::test_named_creation<named_mutex_creation_test_wrapper>();
test::test_all_lock<named_mutex_lock_test_wrapper>();
test::test_all_mutex<false, named_mutex_lock_test_wrapper>();
}
catch(std::exception &ex){
named_mutex::remove("named_mutex");
named_mutex::remove(test::get_compiler_name());
std::cout << ex.what() << std::endl;
return 1;
}
named_mutex::remove("named_mutex");
named_mutex::remove(test::get_compiler_name());
return 0;
}

View File

@@ -14,63 +14,62 @@
#include <boost/date_time/posix_time/posix_time_types.hpp>
#include "mutex_test_template.hpp"
#include "named_creation_template.hpp"
#include <string>
#include "get_compiler_name.hpp"
struct deleter
using namespace boost::interprocess;
struct mutex_deleter
{
~deleter()
{ boost::interprocess::named_recursive_mutex::remove("named_recursive_mutex"); }
~mutex_deleter()
{ named_recursive_mutex::remove(test::get_compiler_name()); }
};
//This wrapper is necessary to have a default constructor
//in generic mutex_test_template functions
class named_recursive_mutex_lock_test_wrapper
: public boost::interprocess::named_recursive_mutex
: public named_recursive_mutex
{
public:
named_recursive_mutex_lock_test_wrapper()
: boost::interprocess::named_recursive_mutex
(boost::interprocess::open_or_create, "named_recursive_mutex")
: named_recursive_mutex(open_or_create, test::get_compiler_name())
{}
};
//This wrapper is necessary to have a common constructor
//in generic named_creation_template functions
class named_mutex_creation_test_wrapper
: public deleter, public boost::interprocess::named_recursive_mutex
: public mutex_deleter, public named_recursive_mutex
{
public:
named_mutex_creation_test_wrapper(boost::interprocess::detail::create_only_t)
: boost::interprocess::named_recursive_mutex
(boost::interprocess::create_only, "named_recursive_mutex")
named_mutex_creation_test_wrapper(create_only_t)
: named_recursive_mutex(create_only, test::get_compiler_name())
{}
named_mutex_creation_test_wrapper(boost::interprocess::detail::open_only_t)
: boost::interprocess::named_recursive_mutex
(boost::interprocess::open_only, "named_recursive_mutex")
named_mutex_creation_test_wrapper(open_only_t)
: named_recursive_mutex(open_only, test::get_compiler_name())
{}
named_mutex_creation_test_wrapper(boost::interprocess::detail::open_or_create_t)
: boost::interprocess::named_recursive_mutex
(boost::interprocess::open_or_create, "named_recursive_mutex")
named_mutex_creation_test_wrapper(open_or_create_t)
: named_recursive_mutex(open_or_create, test::get_compiler_name())
{}
};
int main ()
{
using namespace boost::interprocess;
try{
named_recursive_mutex::remove("named_recursive_mutex");
named_recursive_mutex::remove(test::get_compiler_name());
test::test_named_creation<named_mutex_creation_test_wrapper>();
test::test_all_lock<named_recursive_mutex_lock_test_wrapper>();
test::test_all_mutex<false, named_recursive_mutex_lock_test_wrapper>();
test::test_all_recursive_lock<named_recursive_mutex_lock_test_wrapper>();
}
catch(std::exception &ex){
named_recursive_mutex::remove("named_recursive_mutex");
named_recursive_mutex::remove(test::get_compiler_name());
std::cout << ex.what() << std::endl;
return 1;
}
named_recursive_mutex::remove("named_recursive_mutex");
named_recursive_mutex::remove(test::get_compiler_name());
return 0;
}

View File

@@ -14,41 +14,41 @@
#include <boost/date_time/posix_time/posix_time_types.hpp>
#include "named_creation_template.hpp"
#include "mutex_test_template.hpp"
#include <string>
#include "get_compiler_name.hpp"
using namespace boost::interprocess;
static const std::size_t SemCount = 1;
static const std::size_t RecSemCount = 100;
static const char * SemName = "named_semaphore";
static const char * SemName = test::get_compiler_name();
struct deleter
struct semaphore_deleter
{
~deleter()
{ boost::interprocess::named_semaphore::remove(SemName); }
~semaphore_deleter()
{ named_semaphore::remove(SemName); }
};
//This wrapper is necessary to plug this class
//in named creation tests and interprocess_mutex tests
class named_semaphore_test_wrapper
: public deleter, public boost::interprocess::named_semaphore
: public semaphore_deleter, public named_semaphore
{
public:
named_semaphore_test_wrapper()
: boost::interprocess::named_semaphore
(boost::interprocess::open_or_create, SemName, SemCount)
: named_semaphore(open_or_create, SemName, SemCount)
{}
named_semaphore_test_wrapper(boost::interprocess::detail::create_only_t)
: boost::interprocess::named_semaphore
(boost::interprocess::create_only, SemName, SemCount)
named_semaphore_test_wrapper(create_only_t)
: named_semaphore(create_only, SemName, SemCount)
{}
named_semaphore_test_wrapper(boost::interprocess::detail::open_only_t)
: boost::interprocess::named_semaphore
(boost::interprocess::open_only, SemName)
named_semaphore_test_wrapper(open_only_t)
: named_semaphore(open_only, SemName)
{}
named_semaphore_test_wrapper(boost::interprocess::detail::open_or_create_t)
: boost::interprocess::named_semaphore
(boost::interprocess::open_or_create, SemName, SemCount)
named_semaphore_test_wrapper(open_or_create_t)
: named_semaphore(open_or_create, SemName, SemCount)
{}
~named_semaphore_test_wrapper()
@@ -74,8 +74,7 @@ class named_semaphore_test_wrapper
protected:
named_semaphore_test_wrapper(int initial_count)
: boost::interprocess::named_semaphore
(boost::interprocess::create_only, SemName, initial_count)
: named_semaphore(create_only, SemName, initial_count)
{}
};
@@ -92,8 +91,6 @@ class recursive_named_semaphore_test_wrapper
int main ()
{
using namespace boost::interprocess;
try{
named_semaphore::remove(SemName);
test::test_named_creation<named_semaphore_test_wrapper>();

View File

@@ -13,66 +13,65 @@
#include "sharable_mutex_test_template.hpp"
#include "named_creation_template.hpp"
#include <boost/interprocess/sync/named_upgradable_mutex.hpp>
#include <string>
#include "get_compiler_name.hpp"
struct deleter
using namespace boost::interprocess;
struct mutex_deleter
{
~deleter()
{ boost::interprocess::named_upgradable_mutex::remove("named_upgradable_mutex"); }
~mutex_deleter()
{ named_upgradable_mutex::remove(test::get_compiler_name()); }
};
//This wrapper is necessary to have a default constructor
//in generic mutex_test_template functions
class named_upgradable_mutex_lock_test_wrapper
: public boost::interprocess::named_upgradable_mutex
: public named_upgradable_mutex
{
public:
named_upgradable_mutex_lock_test_wrapper()
: boost::interprocess::named_upgradable_mutex
(boost::interprocess::open_or_create, "named_upgradable_mutex")
: named_upgradable_mutex(open_or_create, test::get_compiler_name())
{}
};
//This wrapper is necessary to have a common constructor
//in generic named_creation_template functions
class named_upgradable_mutex_creation_test_wrapper
: public deleter, public boost::interprocess::named_upgradable_mutex
: public mutex_deleter, public named_upgradable_mutex
{
public:
named_upgradable_mutex_creation_test_wrapper
(boost::interprocess::detail::create_only_t)
: boost::interprocess::named_upgradable_mutex
(boost::interprocess::create_only, "named_upgradable_mutex")
(create_only_t)
: named_upgradable_mutex(create_only, test::get_compiler_name())
{}
named_upgradable_mutex_creation_test_wrapper
(boost::interprocess::detail::open_only_t)
: boost::interprocess::named_upgradable_mutex
(boost::interprocess::open_only, "named_upgradable_mutex")
(open_only_t)
: named_upgradable_mutex(open_only, test::get_compiler_name())
{}
named_upgradable_mutex_creation_test_wrapper
(boost::interprocess::detail::open_or_create_t)
: boost::interprocess::named_upgradable_mutex
(boost::interprocess::open_or_create, "named_upgradable_mutex")
(open_or_create_t)
: named_upgradable_mutex(open_or_create, test::get_compiler_name())
{}
};
int main ()
{
using namespace boost::interprocess;
try{
named_upgradable_mutex::remove("named_upgradable_mutex");
named_upgradable_mutex::remove(test::get_compiler_name());
test::test_named_creation<named_upgradable_mutex_creation_test_wrapper>();
// test::test_all_lock<named_upgradable_mutex_lock_test_wrapper>();
// test::test_all_mutex<true, named_upgradable_mutex_lock_test_wrapper>();
// test::test_all_sharable_mutex<true, named_upgradable_mutex_lock_test_wrapper>();
}
catch(std::exception &ex){
named_upgradable_mutex::remove("named_upgradable_mutex");
named_upgradable_mutex::remove(test::get_compiler_name());
std::cout << ex.what() << std::endl;
return 1;
}
named_upgradable_mutex::remove("named_upgradable_mutex");
named_upgradable_mutex::remove(test::get_compiler_name());
return 0;
}

View File

@@ -15,6 +15,8 @@
#include <boost/interprocess/smart_ptr/segment_deleter.hpp>
#include <vector>
#include <cstddef>
#include <string>
#include "get_compiler_name.hpp"
using namespace boost::interprocess;
@@ -124,17 +126,17 @@ bool test_node_pool<NodePool>::deallocate_free_chunks(NodePool &pool)
return true;
}
template<std::size_t NodeSize, std::size_t NumAlloc>
template<std::size_t NodeSize, std::size_t NodesPerChunk>
bool test_all_node_pool()
{
typedef managed_shared_memory::segment_manager segment_manager;
typedef detail::private_node_pool
<segment_manager, NodeSize, NumAlloc> node_pool_t;
<segment_manager, NodeSize, NodesPerChunk> node_pool_t;
typedef test_node_pool<node_pool_t> test_node_pool_t;
shared_memory_object::remove("MyShm");
shared_memory_object::remove(test::get_compiler_name());
{
managed_shared_memory shm(create_only, "MyShm", 4096);
managed_shared_memory shm(create_only, test::get_compiler_name(), 4096);
typedef segment_deleter<segment_manager, void*> deleter_t;
typedef unique_ptr<node_pool_t, deleter_t> unique_ptr_t;
@@ -150,7 +152,7 @@ bool test_all_node_pool()
if(!test_node_pool_t::deallocate_free_chunks(*p))
return false;
}
shared_memory_object::remove("MyShm");
shared_memory_object::remove(test::get_compiler_name());
return true;
}

View File

@@ -14,6 +14,8 @@
#include <boost/interprocess/mem_algo/simple_seq_fit.hpp>
#include <cstddef>
#include <assert.h>
#include <string>
#include "get_compiler_name.hpp"
using namespace boost::interprocess;
typedef basic_managed_shared_memory
@@ -23,12 +25,12 @@ my_shared_objects_t;
int main ()
{
//Create shared memory
shared_memory_object::remove("MySharedMemory");
shared_memory_object::remove(test::get_compiler_name());
{
my_shared_objects_t segment
(create_only,
"MySharedMemory",//segment name
65536); //segment size in bytes
test::get_compiler_name(), //segment name
65536); //segment size in bytes
//Allocate a portion of the segment
void * shptr = segment.allocate(1024/*bytes to allocate*/);
@@ -42,7 +44,7 @@ int main ()
segment.deallocate(shptr);
}
shared_memory_object::remove("MySharedMemory");
shared_memory_object::remove(test::get_compiler_name());
return 0;
}

View File

@@ -18,6 +18,8 @@
#include <functional>
#include "print_container.hpp"
#include <boost/interprocess/detail/move_iterator.hpp>
#include <string>
#include "get_compiler_name.hpp"
namespace boost{
namespace interprocess{
@@ -32,299 +34,303 @@ int set_test ()
{
typedef typename MyShmSet::value_type IntType;
const int memsize = 65536;
const char *const shMemName = "/MySharedMemory";
const char *const shMemName = test::get_compiler_name();
const int max = 100;
try{
//Create shared memory
shared_memory_object::remove(shMemName);
ManagedSharedMemory segment(create_only, shMemName, memsize);
//Create shared memory
shared_memory_object::remove(shMemName);
ManagedSharedMemory segment(create_only, shMemName, memsize);
segment.reserve_named_objects(100);
segment.reserve_named_objects(100);
//Shared memory allocator must be always be initialized
//since it has no default constructor
MyShmSet *shmset =
segment.template construct<MyShmSet>("MyShmSet")
(std::less<IntType>(), segment.get_segment_manager());
//Shared memory allocator must be always be initialized
//since it has no default constructor
MyShmSet *shmset =
segment.template construct<MyShmSet>("MyShmSet")
(std::less<IntType>(), segment.get_segment_manager());
MyStdSet *stdset = new MyStdSet;
MyStdSet *stdset = new MyStdSet;
MyShmMultiSet *shmmultiset =
segment.template construct<MyShmMultiSet>("MyShmMultiSet")
(std::less<IntType>(), segment.get_segment_manager());
MyShmMultiSet *shmmultiset =
segment.template construct<MyShmMultiSet>("MyShmMultiSet")
(std::less<IntType>(), segment.get_segment_manager());
MyStdMultiSet *stdmultiset = new MyStdMultiSet;
MyStdMultiSet *stdmultiset = new MyStdMultiSet;
//Test construction from a range
{
IntType aux_vect[50];
for(int i = 0; i < 50; ++i){
IntType move_me(i/2);
aux_vect[i] = move(move_me);
}
int aux_vect2[50];
for(int i = 0; i < 50; ++i){
aux_vect2[i] = i/2;
}
IntType aux_vect3[50];
for(int i = 0; i < 50; ++i){
IntType move_me(i/2);
aux_vect3[i] = move(move_me);
}
MyShmSet *shmset2 =
segment.template construct<MyShmSet>("MyShmSet2")
(detail::make_move_iterator(&aux_vect[0])
, detail::make_move_iterator(aux_vect + 50)
, std::less<IntType>(), segment.get_segment_manager());
MyStdSet *stdset2 = new MyStdSet(aux_vect2, aux_vect2 + 50);
MyShmMultiSet *shmmultiset2 =
segment.template construct<MyShmMultiSet>("MyShmMultiSet2")
(detail::make_move_iterator(&aux_vect3[0])
, detail::make_move_iterator(aux_vect3 + 50)
, std::less<IntType>(), segment.get_segment_manager());
MyStdMultiSet *stdmultiset2 = new MyStdMultiSet(aux_vect2, aux_vect2 + 50);
if(!CheckEqualContainers(shmset2, stdset2)) return 1;
if(!CheckEqualContainers(shmmultiset2, stdmultiset2)) return 1;
segment.destroy_ptr(shmset2);
segment.destroy_ptr(shmmultiset2);
delete stdset2;
delete stdmultiset2;
}
int i, j;
for(i = 0; i < max; ++i){
IntType move_me(i);
shmset->insert(move(move_me));
stdset->insert(i);
IntType move_me2(i);
if(i == 9)
i = i;
shmmultiset->insert(move(move_me2));
stdmultiset->insert(i);
}
if(!CheckEqualContainers(shmmultiset, stdmultiset)) return 1;
typename MyShmSet::iterator it;
typename MyShmSet::const_iterator cit = it;
shmset->erase(shmset->begin()++);
stdset->erase(stdset->begin()++);
shmmultiset->erase(shmmultiset->begin()++);
stdmultiset->erase(stdmultiset->begin()++);
if(!CheckEqualContainers(shmset, stdset)) return 1;
if(!CheckEqualContainers(shmmultiset, stdmultiset)) return 1;
shmset->erase(shmset->begin());
stdset->erase(stdset->begin());
shmmultiset->erase(shmmultiset->begin());
stdmultiset->erase(stdmultiset->begin());
if(!CheckEqualContainers(shmset, stdset)) return 1;
if(!CheckEqualContainers(shmmultiset, stdmultiset)) return 1;
//Swapping test
std::less<IntType> lessfunc;
MyShmSet tmpshmeset2 (lessfunc, segment.get_segment_manager());
MyStdSet tmpstdset2;
MyShmMultiSet tmpshmemultiset2(lessfunc, segment.get_segment_manager());
MyStdMultiSet tmpstdmultiset2;
shmset->swap(tmpshmeset2);
stdset->swap(tmpstdset2);
shmmultiset->swap(tmpshmemultiset2);
stdmultiset->swap(tmpstdmultiset2);
shmset->swap(tmpshmeset2);
stdset->swap(tmpstdset2);
shmmultiset->swap(tmpshmemultiset2);
stdmultiset->swap(tmpstdmultiset2);
if(!CheckEqualContainers(shmset, stdset)) return 1;
if(!CheckEqualContainers(shmmultiset, stdmultiset)) return 1;
//Insertion from other container
//Initialize values
{
IntType aux_vect[50];
for(int i = 0; i < 50; ++i){
IntType move_me(-1);
aux_vect[i] = move(move_me);
}
int aux_vect2[50];
for(int i = 0; i < 50; ++i){
aux_vect2[i] = -1;
}
IntType aux_vect3[50];
for(int i = 0; i < 50; ++i){
IntType move_me(-1);
aux_vect3[i] = move(move_me);
}
shmset->insert(detail::make_move_iterator(&aux_vect[0]), detail::make_move_iterator(aux_vect + 50));
stdset->insert(aux_vect2, aux_vect2 + 50);
shmmultiset->insert(detail::make_move_iterator(&aux_vect3[0]), detail::make_move_iterator(aux_vect3 + 50));
stdmultiset->insert(aux_vect2, aux_vect2 + 50);
if(!CheckEqualContainers(shmset, stdset)) return 1;
if(!CheckEqualContainers(shmmultiset, stdmultiset)) return 1;
for(int i = 0, j = static_cast<int>(shmset->size()); i < j; ++i){
IntType erase_me(i);
shmset->erase(erase_me);
stdset->erase(i);
shmmultiset->erase(erase_me);
stdmultiset->erase(i);
}
if(!CheckEqualContainers(shmset, stdset)) return 1;
if(!CheckEqualContainers(shmmultiset, stdmultiset)) return 1;
}
{
IntType aux_vect[50];
for(int i = 0; i < 50; ++i){
IntType move_me(-1);
aux_vect[i] = move(move_me);
}
int aux_vect2[50];
for(int i = 0; i < 50; ++i){
aux_vect2[i] = -1;
}
IntType aux_vect3[50];
for(int i = 0; i < 50; ++i){
IntType move_me(-1);
aux_vect3[i] = move(move_me);
}
IntType aux_vect4[50];
for(int i = 0; i < 50; ++i){
IntType move_me(-1);
aux_vect4[i] = move(move_me);
}
IntType aux_vect5[50];
for(int i = 0; i < 50; ++i){
IntType move_me(-1);
aux_vect5[i] = move(move_me);
}
shmset->insert(detail::make_move_iterator(&aux_vect[0]), detail::make_move_iterator(aux_vect + 50));
shmset->insert(detail::make_move_iterator(&aux_vect3[0]), detail::make_move_iterator(aux_vect3 + 50));
stdset->insert(aux_vect2, aux_vect2 + 50);
stdset->insert(aux_vect2, aux_vect2 + 50);
shmmultiset->insert(detail::make_move_iterator(&aux_vect4[0]), detail::make_move_iterator(aux_vect4 + 50));
shmmultiset->insert(detail::make_move_iterator(&aux_vect5[0]), detail::make_move_iterator(aux_vect5 + 50));
stdmultiset->insert(aux_vect2, aux_vect2 + 50);
stdmultiset->insert(aux_vect2, aux_vect2 + 50);
if(!CheckEqualContainers(shmset, stdset)) return 1;
if(!CheckEqualContainers(shmmultiset, stdmultiset)) return 1;
shmset->erase(*shmset->begin());
stdset->erase(*stdset->begin());
shmmultiset->erase(*shmmultiset->begin());
stdmultiset->erase(*stdmultiset->begin());
if(!CheckEqualContainers(shmset, stdset)) return 1;
if(!CheckEqualContainers(shmmultiset, stdmultiset)) return 1;
}
for(i = 0; i < max; ++i){
IntType move_me(i);
shmset->insert(move(move_me));
stdset->insert(i);
IntType move_me2(i);
shmmultiset->insert(move(move_me2));
stdmultiset->insert(i);
}
if(!CheckEqualContainers(shmset, stdset)) return 1;
if(!CheckEqualContainers(shmmultiset, stdmultiset)) return 1;
for(i = 0; i < max; ++i){
IntType move_me(i);
shmset->insert(shmset->begin(), move(move_me));
stdset->insert(stdset->begin(), i);
//PrintContainers(shmset, stdset);
IntType move_me2(i);
shmmultiset->insert(shmmultiset->begin(), move(move_me2));
stdmultiset->insert(stdmultiset->begin(), i);
//PrintContainers(shmmultiset, stdmultiset);
if(!CheckEqualContainers(shmset, stdset))
return 1;
if(!CheckEqualContainers(shmmultiset, stdmultiset))
return 1;
IntType move_me3(i);
shmset->insert(shmset->end(), move(move_me3));
stdset->insert(stdset->end(), i);
IntType move_me4(i);
shmmultiset->insert(shmmultiset->end(), move(move_me4));
stdmultiset->insert(stdmultiset->end(), i);
if(!CheckEqualContainers(shmset, stdset))
return 1;
if(!CheckEqualContainers(shmmultiset, stdmultiset))
return 1;
//Test construction from a range
{
IntType move_me(i);
shmset->insert(shmset->upper_bound(move_me), move(move_me));
stdset->insert(stdset->upper_bound(i), i);
//PrintContainers(shmset, stdset);
IntType move_me2(i);
shmmultiset->insert(shmmultiset->upper_bound(move_me2), move(move_me2));
stdmultiset->insert(stdmultiset->upper_bound(i), i);
//PrintContainers(shmmultiset, stdmultiset);
if(!CheckEqualContainers(shmset, stdset))
return 1;
if(!CheckEqualContainers(shmmultiset, stdmultiset))
return 1;
IntType aux_vect[50];
for(int i = 0; i < 50; ++i){
IntType move_me(i/2);
aux_vect[i] = move(move_me);
}
int aux_vect2[50];
for(int i = 0; i < 50; ++i){
aux_vect2[i] = i/2;
}
IntType aux_vect3[50];
for(int i = 0; i < 50; ++i){
IntType move_me(i/2);
aux_vect3[i] = move(move_me);
}
MyShmSet *shmset2 =
segment.template construct<MyShmSet>("MyShmSet2")
(detail::make_move_iterator(&aux_vect[0])
, detail::make_move_iterator(aux_vect + 50)
, std::less<IntType>(), segment.get_segment_manager());
MyStdSet *stdset2 = new MyStdSet(aux_vect2, aux_vect2 + 50);
MyShmMultiSet *shmmultiset2 =
segment.template construct<MyShmMultiSet>("MyShmMultiSet2")
(detail::make_move_iterator(&aux_vect3[0])
, detail::make_move_iterator(aux_vect3 + 50)
, std::less<IntType>(), segment.get_segment_manager());
MyStdMultiSet *stdmultiset2 = new MyStdMultiSet(aux_vect2, aux_vect2 + 50);
if(!CheckEqualContainers(shmset2, stdset2)) return 1;
if(!CheckEqualContainers(shmmultiset2, stdmultiset2)) return 1;
segment.destroy_ptr(shmset2);
segment.destroy_ptr(shmmultiset2);
delete stdset2;
delete stdmultiset2;
}
int i, j;
for(i = 0; i < max; ++i){
IntType move_me(i);
shmset->insert(move(move_me));
stdset->insert(i);
IntType move_me2(i);
if(i == 9)
i = i;
shmmultiset->insert(move(move_me2));
stdmultiset->insert(i);
}
if(!CheckEqualContainers(shmmultiset, stdmultiset)) return 1;
typename MyShmSet::iterator it;
typename MyShmSet::const_iterator cit = it;
shmset->erase(shmset->begin()++);
stdset->erase(stdset->begin()++);
shmmultiset->erase(shmmultiset->begin()++);
stdmultiset->erase(stdmultiset->begin()++);
if(!CheckEqualContainers(shmset, stdset)) return 1;
if(!CheckEqualContainers(shmmultiset, stdmultiset)) return 1;
shmset->erase(shmset->begin());
stdset->erase(stdset->begin());
shmmultiset->erase(shmmultiset->begin());
stdmultiset->erase(stdmultiset->begin());
if(!CheckEqualContainers(shmset, stdset)) return 1;
if(!CheckEqualContainers(shmmultiset, stdmultiset)) return 1;
//Swapping test
std::less<IntType> lessfunc;
MyShmSet tmpshmeset2 (lessfunc, segment.get_segment_manager());
MyStdSet tmpstdset2;
MyShmMultiSet tmpshmemultiset2(lessfunc, segment.get_segment_manager());
MyStdMultiSet tmpstdmultiset2;
shmset->swap(tmpshmeset2);
stdset->swap(tmpstdset2);
shmmultiset->swap(tmpshmemultiset2);
stdmultiset->swap(tmpstdmultiset2);
shmset->swap(tmpshmeset2);
stdset->swap(tmpstdset2);
shmmultiset->swap(tmpshmemultiset2);
stdmultiset->swap(tmpstdmultiset2);
if(!CheckEqualContainers(shmset, stdset)) return 1;
if(!CheckEqualContainers(shmmultiset, stdmultiset)) return 1;
//Insertion from other container
//Initialize values
{
IntType aux_vect[50];
for(int i = 0; i < 50; ++i){
IntType move_me(-1);
aux_vect[i] = move(move_me);
}
int aux_vect2[50];
for(int i = 0; i < 50; ++i){
aux_vect2[i] = -1;
}
IntType aux_vect3[50];
for(int i = 0; i < 50; ++i){
IntType move_me(-1);
aux_vect3[i] = move(move_me);
}
shmset->insert(detail::make_move_iterator(&aux_vect[0]), detail::make_move_iterator(aux_vect + 50));
stdset->insert(aux_vect2, aux_vect2 + 50);
shmmultiset->insert(detail::make_move_iterator(&aux_vect3[0]), detail::make_move_iterator(aux_vect3 + 50));
stdmultiset->insert(aux_vect2, aux_vect2 + 50);
if(!CheckEqualContainers(shmset, stdset)) return 1;
if(!CheckEqualContainers(shmmultiset, stdmultiset)) return 1;
for(int i = 0, j = static_cast<int>(shmset->size()); i < j; ++i){
IntType erase_me(i);
shmset->erase(erase_me);
stdset->erase(i);
shmmultiset->erase(erase_me);
stdmultiset->erase(i);
}
if(!CheckEqualContainers(shmset, stdset)) return 1;
if(!CheckEqualContainers(shmmultiset, stdmultiset)) return 1;
}
{
IntType move_me(i);
shmset->insert(shmset->lower_bound(move_me), move(move_me2));
stdset->insert(stdset->lower_bound(i), i);
//PrintContainers(shmset, stdset);
IntType move_me2(i);
shmmultiset->insert(shmmultiset->lower_bound(move_me2), move(move_me2));
stdmultiset->insert(stdmultiset->lower_bound(i), i);
//PrintContainers(shmmultiset, stdmultiset);
if(!CheckEqualContainers(shmset, stdset))
return 1;
if(!CheckEqualContainers(shmmultiset, stdmultiset))
return 1;
IntType aux_vect[50];
for(int i = 0; i < 50; ++i){
IntType move_me(-1);
aux_vect[i] = move(move_me);
}
int aux_vect2[50];
for(int i = 0; i < 50; ++i){
aux_vect2[i] = -1;
}
IntType aux_vect3[50];
for(int i = 0; i < 50; ++i){
IntType move_me(-1);
aux_vect3[i] = move(move_me);
}
IntType aux_vect4[50];
for(int i = 0; i < 50; ++i){
IntType move_me(-1);
aux_vect4[i] = move(move_me);
}
IntType aux_vect5[50];
for(int i = 0; i < 50; ++i){
IntType move_me(-1);
aux_vect5[i] = move(move_me);
}
shmset->insert(detail::make_move_iterator(&aux_vect[0]), detail::make_move_iterator(aux_vect + 50));
shmset->insert(detail::make_move_iterator(&aux_vect3[0]), detail::make_move_iterator(aux_vect3 + 50));
stdset->insert(aux_vect2, aux_vect2 + 50);
stdset->insert(aux_vect2, aux_vect2 + 50);
shmmultiset->insert(detail::make_move_iterator(&aux_vect4[0]), detail::make_move_iterator(aux_vect4 + 50));
shmmultiset->insert(detail::make_move_iterator(&aux_vect5[0]), detail::make_move_iterator(aux_vect5 + 50));
stdmultiset->insert(aux_vect2, aux_vect2 + 50);
stdmultiset->insert(aux_vect2, aux_vect2 + 50);
if(!CheckEqualContainers(shmset, stdset)) return 1;
if(!CheckEqualContainers(shmmultiset, stdmultiset)) return 1;
shmset->erase(*shmset->begin());
stdset->erase(*stdset->begin());
shmmultiset->erase(*shmmultiset->begin());
stdmultiset->erase(*stdmultiset->begin());
if(!CheckEqualContainers(shmset, stdset)) return 1;
if(!CheckEqualContainers(shmmultiset, stdmultiset)) return 1;
}
}
//Compare count with std containers
for(i = 0; i < max; ++i){
IntType count_me(i);
if(shmset->count(count_me) != stdset->count(i)){
return -1;
for(i = 0; i < max; ++i){
IntType move_me(i);
shmset->insert(move(move_me));
stdset->insert(i);
IntType move_me2(i);
shmmultiset->insert(move(move_me2));
stdmultiset->insert(i);
}
if(shmmultiset->count(count_me) != stdmultiset->count(i)){
return -1;
if(!CheckEqualContainers(shmset, stdset)) return 1;
if(!CheckEqualContainers(shmmultiset, stdmultiset)) return 1;
for(i = 0; i < max; ++i){
IntType move_me(i);
shmset->insert(shmset->begin(), move(move_me));
stdset->insert(stdset->begin(), i);
//PrintContainers(shmset, stdset);
IntType move_me2(i);
shmmultiset->insert(shmmultiset->begin(), move(move_me2));
stdmultiset->insert(stdmultiset->begin(), i);
//PrintContainers(shmmultiset, stdmultiset);
if(!CheckEqualContainers(shmset, stdset))
return 1;
if(!CheckEqualContainers(shmmultiset, stdmultiset))
return 1;
IntType move_me3(i);
shmset->insert(shmset->end(), move(move_me3));
stdset->insert(stdset->end(), i);
IntType move_me4(i);
shmmultiset->insert(shmmultiset->end(), move(move_me4));
stdmultiset->insert(stdmultiset->end(), i);
if(!CheckEqualContainers(shmset, stdset))
return 1;
if(!CheckEqualContainers(shmmultiset, stdmultiset))
return 1;
{
IntType move_me(i);
shmset->insert(shmset->upper_bound(move_me), move(move_me));
stdset->insert(stdset->upper_bound(i), i);
//PrintContainers(shmset, stdset);
IntType move_me2(i);
shmmultiset->insert(shmmultiset->upper_bound(move_me2), move(move_me2));
stdmultiset->insert(stdmultiset->upper_bound(i), i);
//PrintContainers(shmmultiset, stdmultiset);
if(!CheckEqualContainers(shmset, stdset))
return 1;
if(!CheckEqualContainers(shmmultiset, stdmultiset))
return 1;
}
{
IntType move_me(i);
shmset->insert(shmset->lower_bound(move_me), move(move_me2));
stdset->insert(stdset->lower_bound(i), i);
//PrintContainers(shmset, stdset);
IntType move_me2(i);
shmmultiset->insert(shmmultiset->lower_bound(move_me2), move(move_me2));
stdmultiset->insert(stdmultiset->lower_bound(i), i);
//PrintContainers(shmmultiset, stdmultiset);
if(!CheckEqualContainers(shmset, stdset))
return 1;
if(!CheckEqualContainers(shmmultiset, stdmultiset))
return 1;
}
}
}
//Now do count exercise
shmset->clear();
shmmultiset->clear();
//Compare count with std containers
for(i = 0; i < max; ++i){
IntType count_me(i);
if(shmset->count(count_me) != stdset->count(i)){
return -1;
}
if(shmmultiset->count(count_me) != stdmultiset->count(i)){
return -1;
}
}
for(j = 0; j < 3; ++j)
for(i = 0; i < 100; ++i){
IntType move_me(i);
shmset->insert(move(move_me));
IntType move_me2(i);
shmmultiset->insert(move(move_me2));
IntType count_me(i);
if(shmset->count(count_me) != typename MyShmMultiSet::size_type(1))
//Now do count exercise
shmset->clear();
shmmultiset->clear();
for(j = 0; j < 3; ++j)
for(i = 0; i < 100; ++i){
IntType move_me(i);
shmset->insert(move(move_me));
IntType move_me2(i);
shmmultiset->insert(move(move_me2));
IntType count_me(i);
if(shmset->count(count_me) != typename MyShmMultiSet::size_type(1))
return 1;
if(shmmultiset->count(count_me) != typename MyShmMultiSet::size_type(j+1))
return 1;
}
segment.template destroy<MyShmSet>("MyShmSet");
delete stdset;
segment.destroy_ptr(shmmultiset);
delete stdmultiset;
segment.shrink_to_fit_indexes();
if(!segment.all_memory_deallocated())
return 1;
if(shmmultiset->count(count_me) != typename MyShmMultiSet::size_type(j+1))
return 1;
}
segment.template destroy<MyShmSet>("MyShmSet");
delete stdset;
segment.destroy_ptr(shmmultiset);
delete stdmultiset;
}
catch(...){
shared_memory_object::remove(shMemName);
@@ -343,65 +349,70 @@ int set_test_copyable ()
{
typedef typename MyShmSet::value_type IntType;
const int memsize = 65536;
const char *const shMemName = "/MySharedMemory";
const char *const shMemName = test::get_compiler_name();
const int max = 100;
try{
//Create shared memory
shared_memory_object::remove(shMemName);
ManagedSharedMemory segment(create_only, shMemName, memsize);
//Create shared memory
shared_memory_object::remove(shMemName);
ManagedSharedMemory segment(create_only, shMemName, memsize);
segment.reserve_named_objects(100);
segment.reserve_named_objects(100);
//Shared memory allocator must be always be initialized
//since it has no default constructor
MyShmSet *shmset =
segment.template construct<MyShmSet>("MyShmSet")
(std::less<IntType>(), segment.get_segment_manager());
//Shared memory allocator must be always be initialized
//since it has no default constructor
MyShmSet *shmset =
segment.template construct<MyShmSet>("MyShmSet")
(std::less<IntType>(), segment.get_segment_manager());
MyStdSet *stdset = new MyStdSet;
MyStdSet *stdset = new MyStdSet;
MyShmMultiSet *shmmultiset =
segment.template construct<MyShmMultiSet>("MyShmMultiSet")
(std::less<IntType>(), segment.get_segment_manager());
MyShmMultiSet *shmmultiset =
segment.template construct<MyShmMultiSet>("MyShmMultiSet")
(std::less<IntType>(), segment.get_segment_manager());
MyStdMultiSet *stdmultiset = new MyStdMultiSet;
MyStdMultiSet *stdmultiset = new MyStdMultiSet;
int i;
for(i = 0; i < max; ++i){
IntType move_me(i);
shmset->insert(move(move_me));
stdset->insert(i);
IntType move_me2(i);
shmmultiset->insert(move(move_me2));
stdmultiset->insert(i);
}
if(!CheckEqualContainers(shmset, stdset)) return 1;
if(!CheckEqualContainers(shmmultiset, stdmultiset)) return 1;
int i;
for(i = 0; i < max; ++i){
IntType move_me(i);
shmset->insert(move(move_me));
stdset->insert(i);
IntType move_me2(i);
shmmultiset->insert(move(move_me2));
stdmultiset->insert(i);
}
if(!CheckEqualContainers(shmset, stdset)) return 1;
if(!CheckEqualContainers(shmmultiset, stdmultiset)) return 1;
{
//Now, test copy constructor
MyShmSet shmsetcopy(*shmset);
MyStdSet stdsetcopy(*stdset);
MyShmMultiSet shmmsetcopy(*shmmultiset);
MyStdMultiSet stdmsetcopy(*stdmultiset);
{
//Now, test copy constructor
MyShmSet shmsetcopy(*shmset);
MyStdSet stdsetcopy(*stdset);
MyShmMultiSet shmmsetcopy(*shmmultiset);
MyStdMultiSet stdmsetcopy(*stdmultiset);
if(!CheckEqualContainers(&shmsetcopy, &stdsetcopy))
if(!CheckEqualContainers(&shmsetcopy, &stdsetcopy))
return 1;
if(!CheckEqualContainers(&shmmsetcopy, &stdmsetcopy))
return 1;
//And now assignment
shmsetcopy = *shmset;
stdsetcopy = *stdset;
shmmsetcopy = *shmmultiset;
stdmsetcopy = *stdmultiset;
if(!CheckEqualContainers(&shmsetcopy, &stdsetcopy))
return 1;
if(!CheckEqualContainers(&shmmsetcopy, &stdmsetcopy))
return 1;
}
segment.destroy_ptr(shmset);
segment.destroy_ptr(shmmultiset);
segment.shrink_to_fit_indexes();
if(!segment.all_memory_deallocated())
return 1;
if(!CheckEqualContainers(&shmmsetcopy, &stdmsetcopy))
return 1;
//And now assignment
shmsetcopy = *shmset;
stdsetcopy = *stdset;
shmmsetcopy = *shmmultiset;
stdmsetcopy = *stdmultiset;
if(!CheckEqualContainers(&shmsetcopy, &stdsetcopy))
return 1;
if(!CheckEqualContainers(&shmmsetcopy, &stdmsetcopy))
return 1;
}
}
catch(...){
shared_memory_object::remove(shMemName);

View File

@@ -13,6 +13,8 @@
#include <iostream>
#include <boost/interprocess/shared_memory_object.hpp>
#include <boost/interprocess/mapped_region.hpp>
#include <string>
#include "get_compiler_name.hpp"
using namespace boost::interprocess;
@@ -22,16 +24,16 @@ int main ()
const std::size_t FileSize = 99999*2;
{
//Remove shared memory
shared_memory_object::remove("my_file");
shared_memory_object::remove(test::get_compiler_name());
//Create shared memory and file mapping
shared_memory_object mapping(create_only, "my_file", read_write);
shared_memory_object mapping(create_only, test::get_compiler_name(), read_write);
mapping.truncate(FileSize);
}
{
//Create a file mapping
shared_memory_object mapping(open_only, "my_file", read_write);
shared_memory_object mapping(open_only, test::get_compiler_name(), read_write);
//Create two mapped regions, one half of the file each
mapped_region region (mapping
@@ -65,7 +67,7 @@ int main ()
//See if the pattern is correct in the file using two mapped regions
{
//Create a file mapping
shared_memory_object mapping(open_only, "my_file", read_write);
shared_memory_object mapping(open_only, test::get_compiler_name(), read_write);
mapped_region region(mapping, read_write, 0, FileSize/2, 0);
mapped_region region2(mapping, read_write, FileSize/2, 0/*FileSize - FileSize/2*/, 0);
@@ -95,7 +97,7 @@ int main ()
//Now check the pattern mapping a single read only mapped_region
{
//Create a file mapping
shared_memory_object mapping(open_only, "my_file", read_only);
shared_memory_object mapping(open_only, test::get_compiler_name(), read_only);
//Create a single regions, mapping all the file
mapped_region region (mapping
@@ -113,10 +115,10 @@ int main ()
}
}
catch(std::exception &exc){
shared_memory_object::remove("my_file");
shared_memory_object::remove(test::get_compiler_name());
std::cout << "Unhandled exception: " << exc.what() << std::endl;
}
shared_memory_object::remove("my_file");
shared_memory_object::remove(test::get_compiler_name());
return 0;
}

View File

@@ -15,15 +15,19 @@
#include "named_creation_template.hpp"
#include <cstring> //for strcmp, memset
#include <iostream> //for cout
#include <string>
#include "get_compiler_name.hpp"
using namespace boost::interprocess;
static const std::size_t ShmSize = 1000;
static const char * ShmName = "shared_memory";
static const char * ShmName = test::get_compiler_name();
struct eraser
{
~eraser()
{
boost::interprocess::shared_memory_object::remove(ShmName);
shared_memory_object::remove(ShmName);
}
};
@@ -31,30 +35,27 @@ struct eraser
//in generic named_creation_template functions
class shared_memory_creation_test_wrapper
: public eraser
, public boost::interprocess::detail::managed_open_or_create_impl
<boost::interprocess::shared_memory_object>
, public detail::managed_open_or_create_impl<shared_memory_object>
{
typedef boost::interprocess::detail::managed_open_or_create_impl
<boost::interprocess::shared_memory_object> shared_memory;
typedef detail::managed_open_or_create_impl<shared_memory_object> shared_memory;
public:
shared_memory_creation_test_wrapper(boost::interprocess::detail::create_only_t)
: shared_memory(boost::interprocess::create_only, ShmName, ShmSize)
shared_memory_creation_test_wrapper(create_only_t)
: shared_memory(create_only, ShmName, ShmSize)
{}
shared_memory_creation_test_wrapper(boost::interprocess::detail::open_only_t)
: shared_memory(boost::interprocess::open_only, ShmName)
shared_memory_creation_test_wrapper(open_only_t)
: shared_memory(open_only, ShmName)
{}
shared_memory_creation_test_wrapper(boost::interprocess::detail::open_or_create_t)
: shared_memory(boost::interprocess::open_or_create, ShmName, ShmSize)
shared_memory_creation_test_wrapper(open_or_create_t)
: shared_memory(open_or_create, ShmName, ShmSize)
{}
};
int main ()
{
using namespace boost::interprocess;
typedef detail::managed_open_or_create_impl<shared_memory_object> shared_memory;
try{

View File

@@ -24,8 +24,8 @@
#include <boost/interprocess/detail/utilities.hpp>
#include <boost/interprocess/smart_ptr/scoped_ptr.hpp>
#include <boost/detail/lightweight_test.hpp>
#include <string>
#include "get_compiler_name.hpp"
using namespace boost::interprocess;
@@ -53,9 +53,12 @@ int simple_test()
typedef shared_ptr<base_class, base_class_allocator, base_deleter_t> base_shared_ptr;
typedef weak_ptr<base_class, base_class_allocator, base_deleter_t> base_weak_ptr;
shared_memory_object::remove("shm_name");
std::string compiler_name;
test::get_compiler_name(compiler_name);
shared_memory_object::remove(compiler_name.c_str());
{
managed_shared_memory shmem(create_only, "shm_name", 10000);
managed_shared_memory shmem(create_only, compiler_name.c_str(), 10000);
{
base_shared_ptr s_ptr(base_shared_ptr::pointer(0),
@@ -87,7 +90,7 @@ int simple_test()
//}
}
}
shared_memory_object::remove("shm_name");
shared_memory_object::remove(compiler_name.c_str());
return 0;
}
@@ -131,10 +134,13 @@ int string_shared_ptr_vector_insertion_test()
typedef vector<string_weak_ptr_t, string_weak_ptr_allocator_t>
string_weak_ptr_vector_t;
std::string compiler_name;
test::get_compiler_name(compiler_name);
//A shared memory managed memory classes
shared_memory_object::remove("shm_name");
shared_memory_object::remove(compiler_name.c_str());
{
managed_shared_memory shmem(create_only, "shm_name", 20000);
managed_shared_memory shmem(create_only, compiler_name.c_str(), 20000);
{
const int NumElements = 100;
@@ -250,7 +256,7 @@ int string_shared_ptr_vector_insertion_test()
string_weak_ptr.reset();
}
}
shared_memory_object::remove("shm_name");
shared_memory_object::remove(compiler_name.c_str());
return 0;
}
//
@@ -410,9 +416,12 @@ int basic_shared_ptr_test()
typedef weak_ptr<Y, v_allocator_t, y_deleter_t> y_weak_ptr;
shared_memory_object::remove("shm_name");
std::string compiler_name;
test::get_compiler_name(compiler_name);
shared_memory_object::remove(compiler_name.c_str());
{
managed_shared_memory shmem(create_only, "shm_name", 10000);
managed_shared_memory shmem(create_only, compiler_name.c_str(), 10000);
{
v_allocator_t v_allocator (shmem.get_segment_manager());
x_deleter_t x_deleter (shmem.get_segment_manager());
@@ -525,7 +534,7 @@ int basic_shared_ptr_test()
BOOST_TEST(cnt == 0);
}
shared_memory_object::remove("shm_name");
shared_memory_object::remove(compiler_name.c_str());
return boost::report_errors();
}

View File

@@ -26,6 +26,7 @@
#include "expand_bwd_test_allocator.hpp"
#include "expand_bwd_test_template.hpp"
#include "allocator_v1.hpp"
#include "get_compiler_name.hpp"
using namespace boost::interprocess;
@@ -78,12 +79,15 @@ int string_test()
const int MaxSize = 100;
std::string compiler_name;
test::get_compiler_name(compiler_name);
//Create shared memory
shared_memory_object::remove("MySharedMemory");
shared_memory_object::remove(compiler_name.c_str());
{
managed_shared_memory segment
(create_only,
"MySharedMemory",//segment name
compiler_name.c_str(),//segment name
65536); //segment size in bytes
ShmemAllocatorChar shmallocator (segment.get_segment_manager());
@@ -260,7 +264,7 @@ int string_test()
segment.destroy_ptr(shmStringVect);
delete stdStringVect;
}
shared_memory_object::remove("MySharedMemory");
shared_memory_object::remove(compiler_name.c_str());
return 0;
}

View File

@@ -13,9 +13,10 @@
#include <boost/interprocess/managed_shared_memory.hpp>
#include <boost/interprocess/containers/set.hpp>
#include <boost/interprocess/containers/map.hpp>
#include <boost/interprocess/allocators/node_allocator.hpp>
#include <boost/interprocess/allocators/allocator.hpp>
#include <boost/interprocess/indexes/map_index.hpp>
#include <boost/interprocess/indexes/iset_index.hpp>
#include <boost/interprocess/mem_algo/simple_seq_fit.hpp>
#include "print_container.hpp"
#include "movable_int.hpp"
#include "dummy_test_allocator.hpp"
@@ -62,22 +63,21 @@ typedef basic_managed_shared_memory
<char,
simple_seq_fit<mutex_family>,
map_index
// iset_index
> my_managed_shared_memory;
//We will work with narrow characters for shared memory objects
//Alias a integer node allocator type
typedef node_allocator<int, my_managed_shared_memory::segment_manager>
shmem_node_allocator_t;
typedef node_allocator<std::pair<const int, int>, my_managed_shared_memory::segment_manager>
typedef allocator<int, my_managed_shared_memory::segment_manager>
shmem_allocator_t;
typedef allocator<std::pair<const int, int>, my_managed_shared_memory::segment_manager>
shmem_node_pair_allocator_t;
typedef node_allocator<test::movable_int, my_managed_shared_memory::segment_manager>
shmem_movable_node_allocator_t;
typedef node_allocator<std::pair<const test::movable_int, test::movable_int>, my_managed_shared_memory::segment_manager>
typedef allocator<test::movable_int, my_managed_shared_memory::segment_manager>
shmem_movable_allocator_t;
typedef allocator<std::pair<const test::movable_int, test::movable_int>, my_managed_shared_memory::segment_manager>
shmem_movable_node_pair_allocator_t;
typedef node_allocator<test::movable_and_copyable_int, my_managed_shared_memory::segment_manager>
shmem_move_copy_node_allocator_t;
typedef node_allocator<std::pair<const test::movable_and_copyable_int, test::movable_and_copyable_int>, my_managed_shared_memory::segment_manager>
typedef allocator<test::movable_and_copyable_int, my_managed_shared_memory::segment_manager>
shmem_move_copy_allocator_t;
typedef allocator<std::pair<const test::movable_and_copyable_int, test::movable_and_copyable_int>, my_managed_shared_memory::segment_manager>
shmem_move_copy_node_pair_allocator_t;
//Alias standard types
@@ -87,17 +87,17 @@ typedef std::map<int, int> MyStdMap;
typedef std::multimap<int, int> MyStdMultiMap;
//Alias non-movable types
typedef set<int, std::less<int>, shmem_node_allocator_t> MyShmSet;
typedef multiset<int, std::less<int>, shmem_node_allocator_t> MyShmMultiSet;
typedef set<int, std::less<int>, shmem_allocator_t> MyShmSet;
typedef multiset<int, std::less<int>, shmem_allocator_t> MyShmMultiSet;
typedef map<int, int, std::less<int>, shmem_node_pair_allocator_t> MyShmMap;
typedef multimap<int, int, std::less<int>, shmem_node_pair_allocator_t> MyShmMultiMap;
//Alias movable types
typedef set<test::movable_int, std::less<test::movable_int>
,shmem_movable_node_allocator_t> MyMovableShmSet;
,shmem_movable_allocator_t> MyMovableShmSet;
typedef multiset<test::movable_int,
std::less<test::movable_int>,
shmem_movable_node_allocator_t> MyMovableShmMultiSet;
shmem_movable_allocator_t> MyMovableShmMultiSet;
typedef map<test::movable_int, test::movable_int,
std::less<test::movable_int>,
shmem_movable_node_pair_allocator_t> MyMovableShmMap;
@@ -107,10 +107,10 @@ typedef multimap<test::movable_int, test::movable_int,
typedef set<test::movable_and_copyable_int
,std::less<test::movable_and_copyable_int>
,shmem_move_copy_node_allocator_t> MyMoveCopyShmSet;
,shmem_move_copy_allocator_t> MyMoveCopyShmSet;
typedef multiset<test::movable_and_copyable_int,
std::less<test::movable_and_copyable_int>,
shmem_move_copy_node_allocator_t> MyMoveCopyShmMultiSet;
shmem_move_copy_allocator_t> MyMoveCopyShmMultiSet;
typedef map<test::movable_and_copyable_int
,test::movable_and_copyable_int
,std::less<test::movable_and_copyable_int>

View File

@@ -22,6 +22,8 @@
#include <boost/interprocess/containers/string.hpp>
#include <boost/interprocess/containers/string.hpp>
#include <stdio.h>
#include <string>
#include "get_compiler_name.hpp"
using namespace boost::interprocess;
@@ -68,10 +70,13 @@ typedef vector <my_unique_ptr_class
int main()
{
std::string compiler_name;
test::get_compiler_name(compiler_name);
//Create managed shared memory
shared_memory_object::remove("mysegment");
shared_memory_object::remove(compiler_name.c_str());
{
managed_shared_memory segment(create_only, "mysegment", 10000);
managed_shared_memory segment(create_only, compiler_name.c_str(), 10000);
//Create unique_ptr using dynamic allocation
my_unique_ptr_class my_ptr (segment.construct<MyClass>(anonymous_instance)()
@@ -99,11 +104,10 @@ int main()
assert(my_ptr2.get() == 0);
assert(list.begin()->get() == ptr1);
assert(list.rbegin()->get() == ptr2);
/*
MyList list2(move(list));
list2.swap(move(MyList(segment.get_segment_manager())));
list.swap(move(MyList(segment.get_segment_manager())));
*/
//MyList list2(move(list));
//list2.swap(move(MyList(segment.get_segment_manager())));
//list.swap(move(MyList(segment.get_segment_manager())));
assert(list.begin()->get() == ptr1);
assert(list.rbegin()->get() == ptr2);
@@ -130,11 +134,9 @@ int main()
assert(set.rbegin()->get() == ptr1);
assert(set.begin()->get() == ptr2);
}
/*
MySet set2(move(set));
set2.swap(move(MySet(set_less_t(), segment.get_segment_manager())));
set.swap(move(MySet(set_less_t(), segment.get_segment_manager())));
*/
//MySet set2(move(set));
//set2.swap(move(MySet(set_less_t(), segment.get_segment_manager())));
//set.swap(move(MySet(set_less_t(), segment.get_segment_manager())));
//Now with vector
MyVector vector(segment.get_segment_manager());
@@ -161,7 +163,7 @@ int main()
assert(vector.begin()->get() == ptr1);
assert(vector.rbegin()->get() == ptr2);
}
shared_memory_object::remove("mysegment");
shared_memory_object::remove(compiler_name.c_str());
return 0;
}

View File

@@ -12,7 +12,6 @@
#include <algorithm>
#include <memory>
#include <vector>
#include <vector>
#include <iostream>
#include <functional>
@@ -31,6 +30,8 @@
#include "expand_bwd_test_allocator.hpp"
#include "expand_bwd_test_template.hpp"
#include "dummy_test_allocator.hpp"
#include <string>
#include "get_compiler_name.hpp"
using namespace boost::interprocess;
@@ -99,8 +100,12 @@ bool do_test()
//Alias vector types
typedef vector<IntType, shmem_allocator_t> MyShmVector;
typedef std::vector<int> MyStdVector;
std::string compiler_name;
test::get_compiler_name(compiler_name);
const int Memsize = 65536;
const char *const shMemName = "MySharedMemory";
const char *const shMemName = compiler_name.c_str();
const int max = 100;
{
@@ -216,6 +221,10 @@ bool do_test()
delete stdvector;
segment.template destroy<MyShmVector>("MyShmVector");
segment.shrink_to_fit_indexes();
if(!segment.all_memory_deallocated())
return false;
}
catch(std::exception &ex){
shared_memory_object::remove(shMemName);

View File

@@ -16,19 +16,24 @@
#include <iostream>
#include <boost/interprocess/windows_shared_memory.hpp>
#include <boost/interprocess/mapped_region.hpp>
#include <string>
#include "get_compiler_name.hpp"
using namespace boost::interprocess;
int main ()
{
std::string compiler_name;
test::get_compiler_name(compiler_name);
try{
const std::size_t FileSize = 99999*2;
//Create shared memory and file mapping
windows_shared_memory mapping(create_only, "my_file", read_write, FileSize);
windows_shared_memory mapping(create_only, compiler_name.c_str(), read_write, FileSize);
{
//Create a file mapping
windows_shared_memory mapping(open_only, "my_file", read_write);
windows_shared_memory mapping(open_only, compiler_name.c_str(), read_write);
//Create two mapped regions, one half of the file each
mapped_region region (mapping
@@ -62,7 +67,7 @@ int main ()
//See if the pattern is correct in the file using two mapped regions
{
//Create a file mapping
windows_shared_memory mapping(open_only, "my_file", read_write);
windows_shared_memory mapping(open_only, compiler_name.c_str(), read_write);
mapped_region region(mapping, read_write, 0, FileSize/2, 0);
mapped_region region2(mapping, read_write, FileSize/2, 0/*FileSize - FileSize/2*/, 0);
@@ -92,7 +97,7 @@ int main ()
//Now check the pattern mapping a single read only mapped_region
{
//Create a file mapping
windows_shared_memory mapping(open_only, "my_file", read_only);
windows_shared_memory mapping(open_only, compiler_name.c_str(), read_only);
//Create a single regions, mapping all the file
mapped_region region (mapping

View File

@@ -19,54 +19,50 @@
#include "named_creation_template.hpp"
#include <cstring> //for strcmp, memset
#include <iostream> //for cout
#include <string> //for string
#include "get_compiler_name.hpp"
using namespace boost::interprocess;
static const char *name_initialization_routine()
{
static std::string compiler_name;
test::get_compiler_name(compiler_name);
return compiler_name.c_str();
}
static const std::size_t ShmSize = 1000;
static const char * ShmName = "windows_shared_memory";
//This wrapper is necessary to have a common constructor
//in generic named_creation_template functions
class shared_memory_creation_test_wrapper
: public boost::interprocess::detail::managed_open_or_create_impl
<boost::interprocess::windows_shared_memory, false>
: public detail::managed_open_or_create_impl
<windows_shared_memory, false>
{
typedef boost::interprocess::detail::managed_open_or_create_impl
<boost::interprocess::windows_shared_memory, false> windows_shared_memory;
typedef detail::managed_open_or_create_impl
<windows_shared_memory, false> windows_shared_memory_t;
public:
shared_memory_creation_test_wrapper(boost::interprocess::detail::create_only_t)
: windows_shared_memory(boost::interprocess::create_only, ShmName, ShmSize)
shared_memory_creation_test_wrapper(create_only_t)
: windows_shared_memory_t(create_only, name_initialization_routine(), ShmSize)
{}
shared_memory_creation_test_wrapper(boost::interprocess::detail::open_only_t)
: windows_shared_memory(boost::interprocess::open_only, ShmName)
shared_memory_creation_test_wrapper(open_only_t)
: windows_shared_memory_t(open_only, name_initialization_routine())
{}
shared_memory_creation_test_wrapper(boost::interprocess::detail::open_or_create_t)
: windows_shared_memory(boost::interprocess::open_or_create, ShmName, ShmSize)
shared_memory_creation_test_wrapper(open_or_create_t)
: windows_shared_memory_t(open_or_create, name_initialization_routine(), ShmSize)
{}
};
int main ()
{
using namespace boost::interprocess;
typedef detail::managed_open_or_create_impl<windows_shared_memory, false> windows_shared_memory;
typedef detail::managed_open_or_create_impl<windows_shared_memory, false> windows_shared_memory_t;
try{
test::test_named_creation<shared_memory_creation_test_wrapper>();
/*
//Create and get name, size and address
{
windows_shared_memory shm1(create_only, ShmName, ShmSize);
//Compare name
if(std::strcmp(shm1.get_name(), ShmName) != 0){
return 1;
}
//Overwrite all memory
std::memset(shm1.get_address(), 0, shm1.get_size());
}*/
}
catch(std::exception &ex){
std::cout << ex.what() << std::endl;