From 19fcec84d8d7d21e796c7624e521b60d28ee21ed Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 20:45:59 +0200 Subject: Adding upstream version 16.2.11+ds. Signed-off-by: Daniel Baumann --- src/boost/libs/pool/CMakeLists.txt | 24 + src/boost/libs/pool/Jamfile | 11 + src/boost/libs/pool/LICENSE | 23 + src/boost/libs/pool/README.md | 34 ++ src/boost/libs/pool/example/Jamfile.v2 | 24 + src/boost/libs/pool/example/sys_allocator.hpp | 109 ++++ src/boost/libs/pool/example/time_pool_alloc.cpp | 558 +++++++++++++++++++++ src/boost/libs/pool/index.html | 13 + src/boost/libs/pool/meta/libraries.json | 14 + src/boost/libs/pool/test/Jamfile.v2 | 49 ++ .../libs/pool/test/pool_msvc_compiler_bug_test.cpp | 40 ++ src/boost/libs/pool/test/random_shuffle.hpp | 26 + src/boost/libs/pool/test/test_bug_1252.cpp | 66 +++ src/boost/libs/pool/test/test_bug_2696.cpp | 66 +++ src/boost/libs/pool/test/test_bug_3349.cpp | 27 + src/boost/libs/pool/test/test_bug_4960.cpp | 45 ++ src/boost/libs/pool/test/test_bug_5526.cpp | 36 ++ .../libs/pool/test/test_msvc_mem_leak_detect.cpp | 50 ++ src/boost/libs/pool/test/test_poisoned_macros.cpp | 50 ++ src/boost/libs/pool/test/test_pool_alloc.cpp | 291 +++++++++++ .../libs/pool/test/test_simple_seg_storage.cpp | 304 +++++++++++ .../libs/pool/test/test_simple_seg_storage.hpp | 173 +++++++ src/boost/libs/pool/test/test_threading.cpp | 80 +++ src/boost/libs/pool/test/test_valgrind_fail_1.cpp | 22 + src/boost/libs/pool/test/test_valgrind_fail_2.cpp | 20 + src/boost/libs/pool/test/track_allocator.hpp | 104 ++++ src/boost/libs/pool/test/valgrind_config_check.cpp | 7 + 27 files changed, 2266 insertions(+) create mode 100644 src/boost/libs/pool/CMakeLists.txt create mode 100644 src/boost/libs/pool/Jamfile create mode 100644 src/boost/libs/pool/LICENSE create mode 100644 src/boost/libs/pool/README.md create mode 100644 src/boost/libs/pool/example/Jamfile.v2 create mode 100644 src/boost/libs/pool/example/sys_allocator.hpp create mode 100644 src/boost/libs/pool/example/time_pool_alloc.cpp create mode 100644 src/boost/libs/pool/index.html create mode 100644 src/boost/libs/pool/meta/libraries.json create mode 100644 src/boost/libs/pool/test/Jamfile.v2 create mode 100644 src/boost/libs/pool/test/pool_msvc_compiler_bug_test.cpp create mode 100644 src/boost/libs/pool/test/random_shuffle.hpp create mode 100644 src/boost/libs/pool/test/test_bug_1252.cpp create mode 100644 src/boost/libs/pool/test/test_bug_2696.cpp create mode 100644 src/boost/libs/pool/test/test_bug_3349.cpp create mode 100644 src/boost/libs/pool/test/test_bug_4960.cpp create mode 100644 src/boost/libs/pool/test/test_bug_5526.cpp create mode 100644 src/boost/libs/pool/test/test_msvc_mem_leak_detect.cpp create mode 100644 src/boost/libs/pool/test/test_poisoned_macros.cpp create mode 100644 src/boost/libs/pool/test/test_pool_alloc.cpp create mode 100644 src/boost/libs/pool/test/test_simple_seg_storage.cpp create mode 100644 src/boost/libs/pool/test/test_simple_seg_storage.hpp create mode 100644 src/boost/libs/pool/test/test_threading.cpp create mode 100644 src/boost/libs/pool/test/test_valgrind_fail_1.cpp create mode 100644 src/boost/libs/pool/test/test_valgrind_fail_2.cpp create mode 100644 src/boost/libs/pool/test/track_allocator.hpp create mode 100644 src/boost/libs/pool/test/valgrind_config_check.cpp (limited to 'src/boost/libs/pool') diff --git a/src/boost/libs/pool/CMakeLists.txt b/src/boost/libs/pool/CMakeLists.txt new file mode 100644 index 000000000..02b32b4f9 --- /dev/null +++ b/src/boost/libs/pool/CMakeLists.txt @@ -0,0 +1,24 @@ +# Copyright 2018 Mike Dev +# 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 +# +# NOTE: CMake support for Boost.Pool is currently experimental at best +# and the interface is likely to change in the future + +cmake_minimum_required(VERSION 3.5) +project(BoostBind LANGUAGES CXX) + +add_library(boost_pool INTERFACE) +add_library(Boost::pool ALIAS boost_pool) + +target_include_directories(boost_pool INTERFACE include) + +target_link_libraries(boost_pool + INTERFACE + Boost::assert + Boost::config + Boost::integer + Boost::throw_exception + Boost::type_traits + Boost::winapi +) diff --git a/src/boost/libs/pool/Jamfile b/src/boost/libs/pool/Jamfile new file mode 100644 index 000000000..6f4d52865 --- /dev/null +++ b/src/boost/libs/pool/Jamfile @@ -0,0 +1,11 @@ +# Boost.Pool Library Jamfile +# +# Copyright (c) 2018 James E. King III +# +# Use, modification, and distribution are subject to 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) + +# please order by name to ease maintenance +build-project example ; +build-project test ; diff --git a/src/boost/libs/pool/LICENSE b/src/boost/libs/pool/LICENSE new file mode 100644 index 000000000..36b7cd93c --- /dev/null +++ b/src/boost/libs/pool/LICENSE @@ -0,0 +1,23 @@ +Boost Software License - Version 1.0 - August 17th, 2003 + +Permission is hereby granted, free of charge, to any person or organization +obtaining a copy of the software and accompanying documentation covered by +this license (the "Software") to use, reproduce, display, distribute, +execute, and transmit the Software, and to prepare derivative works of the +Software, and to permit third-parties to whom the Software is furnished to +do so, all subject to the following: + +The copyright notices in the Software and this entire statement, including +the above license grant, this restriction and the following disclaimer, +must be included in all copies of the Software, in whole or in part, and +all derivative works of the Software, unless such copies or derivative +works are solely in the form of machine-executable object code generated by +a source language processor. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT +SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE +FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/src/boost/libs/pool/README.md b/src/boost/libs/pool/README.md new file mode 100644 index 000000000..ca3f82347 --- /dev/null +++ b/src/boost/libs/pool/README.md @@ -0,0 +1,34 @@ +Pool, part of collection of the [Boost C++ Libraries](http://github.com/boostorg), provides an efficient way to handle memory suballocation for fixed-size items. + +### License + +Distributed under the [Boost Software License, Version 1.0](http://www.boost.org/LICENSE_1_0.txt). + +### Properties + +* C++03 +* Header Only + +### Build Status + +Branch | Travis | Appveyor | Coverity Scan | codecov.io | Deps | Docs | Tests | +:-------------: | ------ | -------- | ------------- | ---------- | ---- | ---- | ----- | +[`master`](https://github.com/boostorg/pool/tree/master) | [![Build Status](https://travis-ci.org/boostorg/pool.svg?branch=master)](https://travis-ci.org/boostorg/pool) | [![Build status](https://ci.appveyor.com/api/projects/status/ci0aakleyrgnw7ji/branch/master?svg=true)](https://ci.appveyor.com/project/jeking3/pool-6s5a4/branch/master) | [![Coverity Scan Build Status](https://scan.coverity.com/projects/15800/badge.svg)](https://scan.coverity.com/projects/boostorg-pool) | [![codecov](https://codecov.io/gh/boostorg/pool/branch/master/graph/badge.svg)](https://codecov.io/gh/boostorg/pool/branch/master)| [![Deps](https://img.shields.io/badge/deps-master-brightgreen.svg)](https://pdimov.github.io/boostdep-report/master/pool.html) | [![Documentation](https://img.shields.io/badge/docs-master-brightgreen.svg)](http://www.boost.org/doc/libs/master/doc/html/pool.html) | [![Enter the Matrix](https://img.shields.io/badge/matrix-master-brightgreen.svg)](http://www.boost.org/development/tests/master/developer/pool.html) +[`develop`](https://github.com/boostorg/pool/tree/develop) | [![Build Status](https://travis-ci.org/boostorg/pool.svg?branch=develop)](https://travis-ci.org/boostorg/pool) | [![Build status](https://ci.appveyor.com/api/projects/status/ci0aakleyrgnw7ji/branch/develop?svg=true)](https://ci.appveyor.com/project/jeking3/pool-6s5a4/branch/develop) | [![Coverity Scan Build Status](https://scan.coverity.com/projects/15800/badge.svg)](https://scan.coverity.com/projects/boostorg-pool) | [![codecov](https://codecov.io/gh/boostorg/pool/branch/develop/graph/badge.svg)](https://codecov.io/gh/boostorg/pool/branch/develop) | [![Deps](https://img.shields.io/badge/deps-develop-brightgreen.svg)](https://pdimov.github.io/boostdep-report/develop/pool.html) | [![Documentation](https://img.shields.io/badge/docs-develop-brightgreen.svg)](http://www.boost.org/doc/libs/develop/doc/html/pool.html) | [![Enter the Matrix](https://img.shields.io/badge/matrix-develop-brightgreen.svg)](http://www.boost.org/development/tests/develop/developer/pool.html) + +### Directories + +| Name | Purpose | +| ----------- | ------------------------------ | +| `doc` | documentation | +| `example` | examples | +| `include` | headers | +| `test` | unit tests | + +### More information + +* [Ask questions](http://stackoverflow.com/questions/ask?tags=c%2B%2B,boost,boost-pool) +* [Report bugs](https://github.com/boostorg/pool/issues): Be sure to mention Boost version, platform and compiler you're using. A small compilable code sample to reproduce the problem is always good as well. +* Submit your patches as pull requests against **develop** branch. Note that by submitting patches you agree to license your modifications under the [Boost Software License, Version 1.0](http://www.boost.org/LICENSE_1_0.txt). +* Discussions about the library are held on the [Boost developers mailing list](http://www.boost.org/community/groups.html#main). Be sure to read the [discussion policy](http://www.boost.org/community/policy.html) before posting and add the `[pool]` tag at the beginning of the subject line. + diff --git a/src/boost/libs/pool/example/Jamfile.v2 b/src/boost/libs/pool/example/Jamfile.v2 new file mode 100644 index 000000000..acb8dcb11 --- /dev/null +++ b/src/boost/libs/pool/example/Jamfile.v2 @@ -0,0 +1,24 @@ +# Boost.Pool Library example Jamfile +# +# Copyright (c) 2008 James E. King III +# +# Distributed under the Boost Software License, Version 1.0. (See accompany- +# ing file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + +import os ; +import testing ; + +project + : requirements + /boost/system//boost_system + BOOST_ALL_NO_LIB=1 + msvc:_SCL_SECURE_NO_WARNINGS + ; + +if ! [ os.environ VALGRIND_OPTS ] +{ +test-suite "pool-examples" + : [ run time_pool_alloc.cpp ] + ; +} + diff --git a/src/boost/libs/pool/example/sys_allocator.hpp b/src/boost/libs/pool/example/sys_allocator.hpp new file mode 100644 index 000000000..50fc052ac --- /dev/null +++ b/src/boost/libs/pool/example/sys_allocator.hpp @@ -0,0 +1,109 @@ +// Copyright (C) 2000 Stephen Cleary +// +// 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) + +#ifndef BOOST_SYS_ALLOCATOR_H +#define BOOST_SYS_ALLOCATOR_H + +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable:4100) +#endif + +// Symbols: malloc_allocator, new_delete_allocator + +#include +#include +#include +#include + +template +struct malloc_allocator +{ + typedef T * pointer; + typedef const T * const_pointer; + typedef T & reference; + typedef const T & const_reference; + typedef T value_type; + + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + + template + struct rebind + { + typedef malloc_allocator other; + }; + + static pointer address(reference r) { return &r; } + static const_pointer address(const_reference r) { return &r; } + static pointer allocate(const size_type n, const void* = 0) + { + const pointer ret = (pointer) std::malloc(n * sizeof(T)); + if (ret == 0) + throw std::bad_alloc(); + return ret; + } + static void deallocate(const pointer p, const size_type) + { std::free(p); } + static size_type max_size() { return (std::numeric_limits::max)(); } + + bool operator==(const malloc_allocator &) const { return true; } + bool operator!=(const malloc_allocator &) const { return false; } + + malloc_allocator() { } + template + malloc_allocator(const malloc_allocator &) { } + + static void construct(const pointer p, const_reference t) + { new ((void *) p) T(t); } + static void destroy(const pointer p) + { p->~T(); } +}; + +template +struct new_delete_allocator +{ + typedef T * pointer; + typedef const T * const_pointer; + typedef T & reference; + typedef const T & const_reference; + typedef T value_type; + + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + + template + struct rebind + { + typedef new_delete_allocator other; + }; + + static pointer address(reference r) { return &r; } + static const_pointer address(const_reference r) { return &r; } + static pointer allocate(const size_type n, const void* = 0) + { return (pointer) new char[n * sizeof(T)]; } + static void deallocate(const pointer p, const size_type) + { delete [] (char*)p; } + static size_type max_size() { return (std::numeric_limits::max)(); } + + bool operator==(const new_delete_allocator &) const { return true; } + bool operator!=(const new_delete_allocator &) const { return false; } + + new_delete_allocator() { } + template + new_delete_allocator(const new_delete_allocator &) { } + + static void construct(const pointer p, const_reference t) + { new ((void *) p) T(t); } + static void destroy(const pointer p) + { p->~T(); } +}; + +#ifdef _MSC_VER +#pragma warning(pop) +#endif + +#endif diff --git a/src/boost/libs/pool/example/time_pool_alloc.cpp b/src/boost/libs/pool/example/time_pool_alloc.cpp new file mode 100644 index 000000000..737c8c265 --- /dev/null +++ b/src/boost/libs/pool/example/time_pool_alloc.cpp @@ -0,0 +1,558 @@ +// Copyright (C) 2000, 2001 Stephen Cleary +// +// 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) + +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include "sys_allocator.hpp" + +unsigned long num_ints; +unsigned long num_loops = 10; +unsigned l; + +template +struct larger_structure +{ + char data[N]; +}; + +unsigned test_number; + +template +static void timing_test_alloc_larger() +{ + typedef boost::fast_pool_allocator, + boost::default_user_allocator_new_delete, + boost::details::pool::null_mutex> alloc; + typedef boost::fast_pool_allocator > alloc_sync; + + double end[1][6]; + std::clock_t start; + + start = std::clock(); + for(l = 0; l < num_loops; ++l) + { + std::allocator > a; + for (unsigned long i = 0; i < num_ints; ++i) + a.deallocate(a.allocate(1), 1); + } + end[0][0] = (std::clock() - start) / ((double) CLOCKS_PER_SEC); + + start = std::clock(); + for(l = 0; l < num_loops; ++l) + { + for (unsigned long i = 0; i < num_ints; ++i) + std::free(std::malloc(sizeof(larger_structure))); + } + end[0][1] = (std::clock() - start) / ((double) CLOCKS_PER_SEC); + + start = std::clock(); + for(l = 0; l < num_loops; ++l) + { + for (unsigned long i = 0; i < num_ints; ++i) + delete new (std::nothrow) larger_structure; + } + end[0][2] = (std::clock() - start) / ((double) CLOCKS_PER_SEC); + + start = std::clock(); + for(l = 0; l < num_loops; ++l) + { + for (unsigned long i = 0; i < num_ints; ++i) + alloc::deallocate(alloc::allocate()); + } + end[0][3] = (std::clock() - start) / ((double) CLOCKS_PER_SEC); + + start = std::clock(); + for(l = 0; l < num_loops; ++l) + { + for (unsigned long i = 0; i < num_ints; ++i) + alloc_sync::deallocate(alloc_sync::allocate()); + } + end[0][4] = (std::clock() - start) / ((double) CLOCKS_PER_SEC); + + start = std::clock(); + for(l = 0; l < num_loops; ++l) + { + boost::pool<> p(sizeof(larger_structure)); + for (unsigned long i = 0; i < num_ints; ++i) + { + void * const t = p.malloc(); + if (t != 0) + p.free(t); + } + } + end[0][5] = (std::clock() - start) / ((double) CLOCKS_PER_SEC); + + std::cout << "Test " << test_number++ << ": Alloc & Dealloc " << num_ints << " structures of size " << sizeof(larger_structure) << ":" << std::endl; + std::cout << " std::allocator: " << end[0][0] << " seconds" << std::endl; + std::cout << " malloc/free: " << end[0][1] << " seconds" << std::endl; + std::cout << " new/delete: " << end[0][2] << " seconds" << std::endl; + std::cout << " Pool Alloc: " << end[0][3] << " seconds" << std::endl; + std::cout << " Pool /w Sync: " << end[0][4] << " seconds" << std::endl; + std::cout << " Pool: " << end[0][5] << " seconds" << std::endl; +} + +static void timing_test_alloc() +{ + typedef boost::fast_pool_allocator alloc; + typedef boost::fast_pool_allocator alloc_sync; + + double end[2][6]; + std::clock_t start; + + int ** p = new int*[num_ints]; + + start = std::clock(); + for(l = 0; l < num_loops; ++l) + { + std::allocator a; + for (unsigned long i = 0; i < num_ints; ++i) + a.deallocate(a.allocate(1), 1); + } + end[0][0] = (std::clock() - start) / ((double) CLOCKS_PER_SEC); + + start = std::clock(); + for(l = 0; l < num_loops; ++l) + { + for (unsigned long i = 0; i < num_ints; ++i) + std::free(std::malloc(sizeof(int))); + } + end[0][1] = (std::clock() - start) / ((double) CLOCKS_PER_SEC); + + start = std::clock(); + for(l = 0; l < num_loops; ++l) + { + for (unsigned long i = 0; i < num_ints; ++i) + delete new (std::nothrow) int; + } + end[0][2] = (std::clock() - start) / ((double) CLOCKS_PER_SEC); + + start = std::clock(); + for(l = 0; l < num_loops; ++l) + { + for (unsigned long i = 0; i < num_ints; ++i) + alloc::deallocate(alloc::allocate()); + } + end[0][3] = (std::clock() - start) / ((double) CLOCKS_PER_SEC); + + start = std::clock(); + for(l = 0; l < num_loops; ++l) + { + for (unsigned long i = 0; i < num_ints; ++i) + alloc_sync::deallocate(alloc_sync::allocate()); + } + end[0][4] = (std::clock() - start) / ((double) CLOCKS_PER_SEC); + + start = std::clock(); + for(l = 0; l < num_loops; ++l) + { + boost::pool<> p2(sizeof(int)); + for (unsigned long i = 0; i < num_ints; ++i) + { + void * const t = p2.malloc(); + if (t != 0) + p2.free(t); + } + } + end[0][5] = (std::clock() - start) / ((double) CLOCKS_PER_SEC); + + + start = std::clock(); + for(l = 0; l < num_loops; ++l) + { + std::allocator a; + for (unsigned long i = 0; i < num_ints; ++i) + p[i] = a.allocate(1); + for (unsigned long i = 0; i < num_ints; ++i) + a.deallocate(p[i], 1); + } + end[1][0] = (std::clock() - start) / ((double) CLOCKS_PER_SEC); + + start = std::clock(); + for(l = 0; l < num_loops; ++l) + { + for (unsigned long i = 0; i < num_ints; ++i) + p[i] = (int *) std::malloc(sizeof(int)); + for (unsigned long i = 0; i < num_ints; ++i) + std::free(p[i]); + } + end[1][1] = (std::clock() - start) / ((double) CLOCKS_PER_SEC); + + start = std::clock(); + for(l = 0; l < num_loops; ++l) + { + for (unsigned long i = 0; i < num_ints; ++i) + p[i] = new (std::nothrow) int; + for (unsigned long i = 0; i < num_ints; ++i) + delete p[i]; + } + end[1][2] = (std::clock() - start) / ((double) CLOCKS_PER_SEC); + + start = std::clock(); + for(l = 0; l < num_loops; ++l) + { + for (unsigned long i = 0; i < num_ints; ++i) + p[i] = alloc::allocate(); + for (unsigned long i = 0; i < num_ints; ++i) + alloc::deallocate(p[i]); + } + end[1][3] = (std::clock() - start) / ((double) CLOCKS_PER_SEC); + + start = std::clock(); + for(l = 0; l < num_loops; ++l) + { + for (unsigned long i = 0; i < num_ints; ++i) + p[i] = alloc_sync::allocate(); + for (unsigned long i = 0; i < num_ints; ++i) + alloc_sync::deallocate(p[i]); + } + end[1][4] = (std::clock() - start) / ((double) CLOCKS_PER_SEC); + + start = std::clock(); + for(l = 0; l < num_loops; ++l) + { + boost::pool<> pl(sizeof(int)); + for (unsigned long i = 0; i < num_ints; ++i) + p[i] = reinterpret_cast(pl.malloc()); + for (unsigned long i = 0; i < num_ints; ++i) + if (p[i] != 0) + pl.free(p[i]); + } + end[1][5] = (std::clock() - start) / ((double) CLOCKS_PER_SEC); + + delete [] p; + + std::cout << "Test 3: Alloc & Dealloc " << num_ints << " ints:" << std::endl; + std::cout << " std::allocator: " << end[0][0] << " seconds" << std::endl; + std::cout << " malloc/free: " << end[0][1] << " seconds" << std::endl; + std::cout << " new/delete: " << end[0][2] << " seconds" << std::endl; + std::cout << " Pool Alloc: " << end[0][3] << " seconds" << std::endl; + std::cout << " Pool /w Sync: " << end[0][4] << " seconds" << std::endl; + std::cout << " Pool: " << end[0][5] << " seconds" << std::endl; + + std::cout << "Test 4: Alloc " << num_ints << " ints & Dealloc " << num_ints << " ints:" << std::endl; + std::cout << " std::allocator: " << end[1][0] << " seconds" << std::endl; + std::cout << " malloc/free: " << end[1][1] << " seconds" << std::endl; + std::cout << " new/delete: " << end[1][2] << " seconds" << std::endl; + std::cout << " Pool Alloc: " << end[1][3] << " seconds" << std::endl; + std::cout << " Pool /w Sync: " << end[1][4] << " seconds" << std::endl; + std::cout << " Pool: " << end[1][5] << " seconds" << std::endl; +} + +static void timing_test_containers() +{ + typedef boost::pool_allocator alloc; + typedef boost::pool_allocator alloc_sync; + typedef boost::fast_pool_allocator fast_alloc; + typedef boost::fast_pool_allocator fast_alloc_sync; + + double end[3][5]; + std::clock_t start; + + start = std::clock(); + for(l = 0; l < num_loops; ++l) + { + std::vector > x; + for (unsigned long i = 0; i < num_ints; ++i) + x.push_back(0); + } + end[0][0] = (std::clock() - start) / ((double) CLOCKS_PER_SEC); + + start = std::clock(); + for(l = 0; l < num_loops; ++l) + { + std::vector > x; + for (unsigned long i = 0; i < num_ints; ++i) + x.push_back(0); + } + end[0][1] = (std::clock() - start) / ((double) CLOCKS_PER_SEC); + + start = std::clock(); + for(l = 0; l < num_loops; ++l) + { + std::vector > x; + for (unsigned long i = 0; i < num_ints; ++i) + x.push_back(0); + } + end[0][2] = (std::clock() - start) / ((double) CLOCKS_PER_SEC); + + start = std::clock(); + for(l = 0; l < num_loops; ++l) + { + std::vector x; + for (unsigned long i = 0; i < num_ints; ++i) + x.push_back(0); + } + end[0][3] = (std::clock() - start) / ((double) CLOCKS_PER_SEC); + + start = std::clock(); + for(l = 0; l < num_loops; ++l) + { + std::vector x; + for (unsigned long i = 0; i < num_ints; ++i) + x.push_back(0); + } + end[0][4] = (std::clock() - start) / ((double) CLOCKS_PER_SEC); + + + start = std::clock(); + for(l = 0; l < num_loops; ++l) + { + std::set, std::allocator > x; + for (unsigned long i = 0; i < num_ints; ++i) + x.insert(0); + } + end[1][0] = (std::clock() - start) / ((double) CLOCKS_PER_SEC); + + start = std::clock(); + for(l = 0; l < num_loops; ++l) + { + std::set, malloc_allocator > x; + for (unsigned long i = 0; i < num_ints; ++i) + x.insert(0); + } + end[1][1] = (std::clock() - start) / ((double) CLOCKS_PER_SEC); + + start = std::clock(); + for(l = 0; l < num_loops; ++l) + { + std::set, new_delete_allocator > x; + for (unsigned long i = 0; i < num_ints; ++i) + x.insert(0); + } + end[1][2] = (std::clock() - start) / ((double) CLOCKS_PER_SEC); + + start = std::clock(); + for(l = 0; l < num_loops; ++l) + { + std::set, fast_alloc> x; + for (unsigned long i = 0; i < num_ints; ++i) + x.insert(0); + } + end[1][3] = (std::clock() - start) / ((double) CLOCKS_PER_SEC); + + start = std::clock(); + for(l = 0; l < num_loops; ++l) + { + std::set, fast_alloc_sync> x; + for (unsigned long i = 0; i < num_ints; ++i) + x.insert(0); + } + end[1][4] = (std::clock() - start) / ((double) CLOCKS_PER_SEC); + + + start = std::clock(); + for(l = 0; l < num_loops; ++l) + { + std::list > x; + for (unsigned long i = 0; i < num_ints; ++i) + x.push_back(0); + } + end[2][0] = (std::clock() - start) / ((double) CLOCKS_PER_SEC); + + start = std::clock(); + for(l = 0; l < num_loops; ++l) + { + std::list > x; + for (unsigned long i = 0; i < num_ints; ++i) + x.push_back(0); + } + end[2][1] = (std::clock() - start) / ((double) CLOCKS_PER_SEC); + + start = std::clock(); + for(l = 0; l < num_loops; ++l) + { + std::list > x; + for (unsigned long i = 0; i < num_ints; ++i) + x.push_back(0); + } + end[2][2] = (std::clock() - start) / ((double) CLOCKS_PER_SEC); + + start = std::clock(); + for(l = 0; l < num_loops; ++l) + { + std::list x; + for (unsigned long i = 0; i < num_ints; ++i) + x.push_back(0); + } + end[2][3] = (std::clock() - start) / ((double) CLOCKS_PER_SEC); + + start = std::clock(); + for(l = 0; l < num_loops; ++l) + { + std::list x; + for (unsigned long i = 0; i < num_ints; ++i) + x.push_back(0); + } + end[2][4] = (std::clock() - start) / ((double) CLOCKS_PER_SEC); + + std::cout << "Test 0: Insertion & deletion of " << num_ints << " ints in a vector:" << std::endl; + std::cout << " std::allocator: " << end[0][0] << " seconds" << std::endl; + std::cout << " malloc/free: " << end[0][1] << " seconds" << std::endl; + std::cout << " new/delete: " << end[0][2] << " seconds" << std::endl; + std::cout << " Pool Alloc: " << end[0][3] << " seconds" << std::endl; + std::cout << " Pool /w Sync: " << end[0][4] << " seconds" << std::endl; + std::cout << " Pool: not possible" << std::endl; + std::cout << "Test 1: Insertion & deletion of " << num_ints << " ints in a set:" << std::endl; + std::cout << " std::allocator: " << end[1][0] << " seconds" << std::endl; + std::cout << " malloc/free: " << end[1][1] << " seconds" << std::endl; + std::cout << " new/delete: " << end[1][2] << " seconds" << std::endl; + std::cout << " Pool Alloc: " << end[1][3] << " seconds" << std::endl; + std::cout << " Pool /w Sync: " << end[1][4] << " seconds" << std::endl; + std::cout << " Pool: not possible" << std::endl; + std::cout << "Test 2: Insertion & deletion of " << num_ints << " ints in a list:" << std::endl; + std::cout << " std::allocator: " << end[2][0] << " seconds" << std::endl; + std::cout << " malloc/free: " << end[2][1] << " seconds" << std::endl; + std::cout << " new/delete: " << end[2][2] << " seconds" << std::endl; + std::cout << " Pool Alloc: " << end[2][3] << " seconds" << std::endl; + std::cout << " Pool /w Sync: " << end[2][4] << " seconds" << std::endl; + std::cout << " Pool: not possible" << std::endl; +} + +int main(int argc, char * argv[]) +{ + if (argc != 1 && argc != 2) + { + std::cerr << "Usage: " << argv[0] + << " [number_of_ints_to_use_each_try]" << std::endl; + return 1; + } + + errno = 0; + + if (argc == 2) + { + num_ints = std::strtoul(argv[1], 0, 10); + if (errno != 0) + { + std::cerr << "Cannot convert number \"" << argv[1] << '"' << std::endl; + return 2; + } + } + else + num_ints = 700000; + +#ifndef _NDEBUG + num_ints /= 100; +#endif + + try + { + timing_test_containers(); + timing_test_alloc(); + test_number = 5; + timing_test_alloc_larger<64>(); + test_number = 6; + timing_test_alloc_larger<256>(); + test_number = 7; + timing_test_alloc_larger<4096>(); + } + catch (const std::bad_alloc &) + { + std::cerr << "Timing tests ran out of memory; try again with a lower value for number of ints" + << " (current value is " << num_ints << ")" << std::endl; + return 3; + } + catch (const std::exception & e) + { + std::cerr << "Error: " << e.what() << std::endl; + return 4; + } + catch (...) + { + std::cerr << "Unknown error" << std::endl; + return 5; + } + + return 0; +} + +/* + +Output: + +MSVC 10.0 using mutli-threaded DLL + + time_pool_alloc.cpp + Creating library J:\Cpp\pool\pool\Release\alloc_example.lib and object J:\Cpp\pool\pool\Release\alloc_example.exp + Generating code + Finished generating code + alloc_example.vcxproj -> J:\Cpp\pool\pool\Release\alloc_example.exe + Test 0: Insertion & deletion of 700000 ints in a vector: + std::allocator: 0.062 seconds + malloc/free: 0.078 seconds + new/delete: 0.078 seconds + Pool Alloc: 0.328 seconds + Pool /w Sync: 0.343 seconds + Pool: not possible + Test 1: Insertion & deletion of 700000 ints in a set: + std::allocator: 0.561 seconds + malloc/free: 0.546 seconds + new/delete: 0.562 seconds + Pool Alloc: 0.109 seconds + Pool /w Sync: 0.094 seconds + Pool: not possible + Test 2: Insertion & deletion of 700000 ints in a list: + std::allocator: 0.671 seconds + malloc/free: 0.67 seconds + new/delete: 0.671 seconds + Pool Alloc: 0.094 seconds + Pool /w Sync: 0.093 seconds + Pool: not possible + Test 3: Alloc & Dealloc 700000 ints: + std::allocator: 0.5 seconds + malloc/free: 0.468 seconds + new/delete: 0.592 seconds + Pool Alloc: 0.032 seconds + Pool /w Sync: 0.015 seconds + Pool: 0.016 seconds + Test 4: Alloc 700000 ints & Dealloc 700000 ints: + std::allocator: 0.593 seconds + malloc/free: 0.577 seconds + new/delete: 0.717 seconds + Pool Alloc: 0.032 seconds + Pool /w Sync: 0.031 seconds + Pool: 0.047 seconds + Test 5: Alloc & Dealloc 700000 structures of size 64: + std::allocator: 0.499 seconds + malloc/free: 0.483 seconds + new/delete: 0.624 seconds + Pool Alloc: 0.016 seconds + Pool /w Sync: 0.031 seconds + Pool: 0.016 seconds + Test 6: Alloc & Dealloc 700000 structures of size 256: + std::allocator: 0.499 seconds + malloc/free: 0.484 seconds + new/delete: 0.639 seconds + Pool Alloc: 0.016 seconds + Pool /w Sync: 0.015 seconds + Pool: 0.016 seconds + Test 7: Alloc & Dealloc 700000 structures of size 4096: + std::allocator: 0.515 seconds + malloc/free: 0.515 seconds + new/delete: 0.639 seconds + Pool Alloc: 0.031 seconds + Pool /w Sync: 0.016 seconds + Pool: 0.016 seconds + +*/ + + + diff --git a/src/boost/libs/pool/index.html b/src/boost/libs/pool/index.html new file mode 100644 index 000000000..2231706a7 --- /dev/null +++ b/src/boost/libs/pool/index.html @@ -0,0 +1,13 @@ + + + + + +Automatic redirection failed, please go to +doc/html/index.html
+

© Copyright Beman Dawes, 2001

+

Distributed under the Boost Software License, Version 1.0. (See accompanying +file LICENSE_1_0.txt or copy +at www.boost.org/LICENSE_1_0.txt)

+ + diff --git a/src/boost/libs/pool/meta/libraries.json b/src/boost/libs/pool/meta/libraries.json new file mode 100644 index 000000000..b03ef3a1f --- /dev/null +++ b/src/boost/libs/pool/meta/libraries.json @@ -0,0 +1,14 @@ +{ + "key": "pool", + "name": "Pool", + "authors": [ + "Steve Cleary" + ], + "description": "Memory pool management.", + "category": [ + "Memory" + ], + "maintainers": [ + "Stephen Cleary " + ] +} diff --git a/src/boost/libs/pool/test/Jamfile.v2 b/src/boost/libs/pool/test/Jamfile.v2 new file mode 100644 index 000000000..9e96abcbd --- /dev/null +++ b/src/boost/libs/pool/test/Jamfile.v2 @@ -0,0 +1,49 @@ +#~ Copyright Rene Rivera 2008 +#~ Copyright James E. King III 2018 +#~ 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) + + +project + : requirements + /boost/system//boost_system + BOOST_ALL_NO_LIB=1 + all + clang:-Wextra + clang:-Wno-variadic-macros + gcc:-Wextra + gcc:-Wshadow + gcc:-Wno-variadic-macros + msvc:_SCL_SECURE_NO_WARNINGS + ; + +import common ; +import os ; +import testing ; + +test-suite pool : + [ run test_simple_seg_storage.cpp : : : msvc:-wd4267 ] + [ run test_pool_alloc.cpp ] + [ run pool_msvc_compiler_bug_test.cpp : : : msvc:-wd4512 ] + [ run test_msvc_mem_leak_detect.cpp ] + [ run test_bug_3349.cpp ] + [ run test_bug_4960.cpp ] + [ run test_bug_1252.cpp : : : + clang:-Wno-c++11-long-long + gcc:-Wno-long-long + pathscale:-Wno-long-long ] + [ run test_bug_2696.cpp ] + [ run test_bug_5526.cpp ] + [ run test_threading.cpp : : : multi /boost/thread//boost_thread ] + [ compile test_poisoned_macros.cpp ] + ; + +if [ os.environ VALGRIND_OPTS ] +{ +test-suite pool-valgrind : + [ run test_pool_alloc.cpp : : : BOOST_POOL_VALGRIND=1 : test_pool_alloc_valgrind ] + [ run-fail test_valgrind_fail_1.cpp : : : BOOST_POOL_VALGRIND=1 ] + [ run-fail test_valgrind_fail_2.cpp : : : BOOST_POOL_VALGRIND=1 ] + ; +} + diff --git a/src/boost/libs/pool/test/pool_msvc_compiler_bug_test.cpp b/src/boost/libs/pool/test/pool_msvc_compiler_bug_test.cpp new file mode 100644 index 000000000..e188c4701 --- /dev/null +++ b/src/boost/libs/pool/test/pool_msvc_compiler_bug_test.cpp @@ -0,0 +1,40 @@ +// Copyright (C) 2008 Jurko Gospodnetic +// +// 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) + + +// This tests whether the Boost Pool library managed to get a regression and +// hit the MSVC 'variables exported to global namespace' bug again. This bug +// affects at least MSVC 7.1 & 8.0 releases and has been fixed in the MSVC 9.0 +// release. +// +// If the bug exists this test should fail to compile, complaining about an +// ambiguous CRITICAL_SECTION symbol. The bug got fixed by making the boost/ +// /pool/detail/mutex.hpp header reference all Windows API constants using their +// fully qualified names. +// +// To see the bug in action without using any Boost libraries run the +// following program: +// +// namespace One { class Brick; } +// namespace Two +// { +// using namespace One; +// template class TinyClass {}; +// } +// class Brick {}; +// Brick brick; +// int main() {} +// (17.04.2008.) (Jurko) + + +#include "boost/archive/text_iarchive.hpp" +#include "boost/pool/detail/mutex.hpp" +// Including "boost/pool/pool_alloc.hpp" instead of mutex.hpp should work as +// well. + +int main() +{ +} diff --git a/src/boost/libs/pool/test/random_shuffle.hpp b/src/boost/libs/pool/test/random_shuffle.hpp new file mode 100644 index 000000000..1bc545238 --- /dev/null +++ b/src/boost/libs/pool/test/random_shuffle.hpp @@ -0,0 +1,26 @@ +/* Copyright (C) 2016 Edward Diener +* +* Use, modification and distribution is subject to the +* Boost Software License, Version 1.0. (See accompanying +* file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_POOL_TEST_RANDOM_SHUFFLE_HPP +#define BOOST_POOL_TEST_RANDOM_SHUFFLE_HPP + +#include +#include +#include + +template< class RandomIt > +void pool_test_random_shuffle( RandomIt first, RandomIt last ) +{ + typename std::iterator_traits::difference_type i, n; + n = last - first; + for (i = n-1; i > 0; --i) { + using std::swap; + swap(first[i], first[std::rand() % (i+1)]); + } +} + +#endif // BOOST_POOL_TEST_RANDOM_SHUFFLE_HPP diff --git a/src/boost/libs/pool/test/test_bug_1252.cpp b/src/boost/libs/pool/test/test_bug_1252.cpp new file mode 100644 index 000000000..18830571e --- /dev/null +++ b/src/boost/libs/pool/test/test_bug_1252.cpp @@ -0,0 +1,66 @@ +/* Copyright (C) 2011 John Maddock +* +* Use, modification and distribution is subject to the +* Boost Software License, Version 1.0. (See accompanying +* file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) +*/ + +// Test of bug #1252 (https://svn.boost.org/trac/boost/ticket/1252) + +#include +#include +#include +#include + +struct limited_allocator_new_delete +{ + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + + static char * malloc BOOST_PREVENT_MACRO_SUBSTITUTION(const size_type bytes) + { + if(bytes > 1510 * 32) + return 0; + return new (std::nothrow) char[bytes]; + } + static void free BOOST_PREVENT_MACRO_SUBSTITUTION(char * const block) + { + delete [] block; + } +}; + +template +void test_alignment(T) +{ + unsigned align = boost::alignment_of::value; + boost::pool<> p(sizeof(T)); + unsigned limit = 100000; + for(unsigned i = 0; i < limit; ++i) + { + void* ptr = (p.malloc)(); + BOOST_TEST(reinterpret_cast(ptr) % align == 0); + // Trample over the memory just to be sure the allocated block is big enough, + // if it's not, we'll trample over the next block as well (and our internal housekeeping). + std::memset(ptr, 0xff, sizeof(T)); + } +} + + +int main() +{ + boost::pool po(1501); + void* p = (po.malloc)(); + BOOST_TEST(p != 0); + + test_alignment(char(0)); + test_alignment(short(0)); + test_alignment(int(0)); + test_alignment(long(0)); + test_alignment(double(0)); + test_alignment(float(0)); + test_alignment((long double)(0)); +#ifndef BOOST_NO_LONG_LONG + test_alignment((long long)(0)); +#endif + return boost::report_errors(); +} diff --git a/src/boost/libs/pool/test/test_bug_2696.cpp b/src/boost/libs/pool/test/test_bug_2696.cpp new file mode 100644 index 000000000..9b72b3d65 --- /dev/null +++ b/src/boost/libs/pool/test/test_bug_2696.cpp @@ -0,0 +1,66 @@ +/* Copyright (C) 2011 John Maddock +* +* Use, modification and distribution is subject to the +* Boost Software License, Version 1.0. (See accompanying +* file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) +*/ + +// Test of bug #2696 (https://svn.boost.org/trac/boost/ticket/2696) + +#include +#include + +struct limited_allocator_new_delete +{ + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + + static char * malloc BOOST_PREVENT_MACRO_SUBSTITUTION(const size_type bytes) + { +#ifndef BOOST_POOL_VALGRIND + static const unsigned max_size = sizeof(void*) * 40 + boost::integer::static_lcm::value + sizeof(size_type); +#else + static const unsigned max_size = sizeof(void*) * 40; +#endif + if(bytes > max_size) + return 0; + return new (std::nothrow) char[bytes]; + } + static void free BOOST_PREVENT_MACRO_SUBSTITUTION(char * const block) + { + delete [] block; + } +}; + +int main() +{ + static const unsigned alloc_size = sizeof(void*); + boost::pool p1(alloc_size, 10, 40); + for(int i = 1; i <= 40; ++i) + BOOST_TEST((p1.ordered_malloc)(i)); + BOOST_TEST(p1.ordered_malloc(42) == 0); + // + // If the largest block is 40, and we start with 10, we get 10+20+40 elements before + // we actually run out of memory: + // + boost::pool p2(alloc_size, 10, 40); + for(int i = 1; i <= 70; ++i) + BOOST_TEST((p2.malloc)()); + boost::pool p2b(alloc_size, 10, 40); + for(int i = 1; i <= 100; ++i) + BOOST_TEST((p2b.ordered_malloc)()); + // + // Try again with no explicit upper limit: + // + boost::pool p3(alloc_size); + for(int i = 1; i <= 40; ++i) + BOOST_TEST((p3.ordered_malloc)(i)); + BOOST_TEST(p3.ordered_malloc(42) == 0); + boost::pool p4(alloc_size, 10); + for(int i = 1; i <= 100; ++i) + BOOST_TEST((p4.ordered_malloc)()); + boost::pool p5(alloc_size, 10); + for(int i = 1; i <= 100; ++i) + BOOST_TEST((p5.malloc)()); + return boost::report_errors(); +} diff --git a/src/boost/libs/pool/test/test_bug_3349.cpp b/src/boost/libs/pool/test/test_bug_3349.cpp new file mode 100644 index 000000000..57269d0f8 --- /dev/null +++ b/src/boost/libs/pool/test/test_bug_3349.cpp @@ -0,0 +1,27 @@ +/* Copyright (C) 2011 Kwan Ting Chan + * Based from bug report submitted by Xiaohan Wang + * + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + */ + +// Test of bug #3349 (https://svn.boost.org/trac/boost/ticket/3349) + +#include + +#include + +int main() +{ + boost::pool<> p(256, 4); + + void* pBlock1 = p.ordered_malloc( 1 ); + void* pBlock2 = p.ordered_malloc( 4 ); + (void)pBlock2; // warning suppression + + p.ordered_free( pBlock1 ); + + BOOST_TEST(p.release_memory()); + return boost::report_errors(); +} diff --git a/src/boost/libs/pool/test/test_bug_4960.cpp b/src/boost/libs/pool/test/test_bug_4960.cpp new file mode 100644 index 000000000..e95f714ec --- /dev/null +++ b/src/boost/libs/pool/test/test_bug_4960.cpp @@ -0,0 +1,45 @@ +/* Copyright (C) 2011 Kwan Ting Chan + * Based from bug report submitted by Xiaohan Wang + * + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + */ + +// Test of bug #4960 (https://svn.boost.org/trac/boost/ticket/4960) + +#include +#include +#include + +typedef std::vector > EventVector; +typedef std::vector > IndexVector; + +int main() +{ + IndexVector iv; + int limit = 100; + for (int i = 0; i < limit; ++i) + { + iv.push_back(EventVector()); + for(int j = 0; j < limit; ++j) + iv.back().push_back(j); + } + + boost::pool po(4); + for(int i = 0; i < limit; ++i) + { + void* p = po.ordered_malloc(0); + po.ordered_free(p, 0); + } + + boost::pool_allocator al; + for(int i = 0; i < limit; ++i) + { + int* p = al.allocate(0); + al.deallocate(p, 0); + } + + std::cout << "it works\n"; + return 0; +} diff --git a/src/boost/libs/pool/test/test_bug_5526.cpp b/src/boost/libs/pool/test/test_bug_5526.cpp new file mode 100644 index 000000000..a23994a54 --- /dev/null +++ b/src/boost/libs/pool/test/test_bug_5526.cpp @@ -0,0 +1,36 @@ +/* Copyright (C) 2011 John Maddock +* +* Use, modification and distribution is subject to the +* Boost Software License, Version 1.0. (See accompanying +* file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) +*/ + +// Test of bug #5526 (https://svn.boost.org/trac/boost/ticket/5526) + +#include +#include +#include +#include + +struct bad +{ + bad() + { + buf = static_cast(boost::singleton_pool::malloc()); + *buf = 0x1234; + } + ~bad() + { + BOOST_ASSERT(*buf == 0x1234); + boost::singleton_pool::free(buf); + } + int* buf; +}; + +boost::scoped_ptr aptr; + +int main() +{ + aptr.reset(new bad()); + return 0; +} diff --git a/src/boost/libs/pool/test/test_msvc_mem_leak_detect.cpp b/src/boost/libs/pool/test/test_msvc_mem_leak_detect.cpp new file mode 100644 index 000000000..3a80f168d --- /dev/null +++ b/src/boost/libs/pool/test/test_msvc_mem_leak_detect.cpp @@ -0,0 +1,50 @@ +/* Copyright (C) 2011 Kwan Ting Chan + * + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + */ + +// Test of bug #4346 (https://svn.boost.org/trac/boost/ticket/4346) + +#ifdef _MSC_VER +#define _CRTDBG_MAP_ALLOC +#include +#include +#endif + +#include +#include +#include +#include +#include +#include + +#include + +struct Foo {}; + +int main() +{ + { + boost::pool<> p(sizeof(int)); + (p.malloc)(); + } + + { + boost::object_pool p; + (p.malloc)(); + } + + { + (boost::singleton_pool::malloc)(); + } + boost::singleton_pool::purge_memory(); + + { + std::vector > v; + v.push_back(8); + } + boost::singleton_pool::release_memory(); +} diff --git a/src/boost/libs/pool/test/test_poisoned_macros.cpp b/src/boost/libs/pool/test/test_poisoned_macros.cpp new file mode 100644 index 000000000..072122c2f --- /dev/null +++ b/src/boost/libs/pool/test/test_poisoned_macros.cpp @@ -0,0 +1,50 @@ +/* Copyright (C) 2011 John Maddock +* +* Use, modification and distribution is subject to the +* Boost Software License, Version 1.0. (See accompanying +* file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) +*/ + +// +// Verify that if malloc/free are macros that everything still works OK: +// + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace std{ + + void* undefined_poisoned_symbol1(unsigned x); + void undefined_poisoned_symbol2(void* x); + +} + +#define malloc(x) undefined_poisoned_symbol1(x) +#define free(x) undefined_poisoned_symbol2(x) + +#include +#include +#include +#include + +template class boost::object_pool; +template class boost::object_pool; + +template class boost::pool; +template class boost::pool; + +template class boost::pool_allocator; +template class boost::pool_allocator; +template class boost::fast_pool_allocator; +template class boost::fast_pool_allocator; + +template class boost::simple_segregated_storage; + +template class boost::singleton_pool; diff --git a/src/boost/libs/pool/test/test_pool_alloc.cpp b/src/boost/libs/pool/test/test_pool_alloc.cpp new file mode 100644 index 000000000..b0b50eabe --- /dev/null +++ b/src/boost/libs/pool/test/test_pool_alloc.cpp @@ -0,0 +1,291 @@ +/* Copyright (C) 2000, 2001 Stephen Cleary + * Copyright (C) 2011 Kwan Ting Chan + * + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + */ + +#include "random_shuffle.hpp" +#include +#include + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +// Each "tester" object below checks into and out of the "cdtor_checker", +// which will check for any problems related to the construction/destruction of +// "tester" objects. +class cdtor_checker +{ +private: + // Each constructed object registers its "this" pointer into "objs" + std::set objs; + +public: + // True iff all objects that have checked in have checked out + bool ok() const { return objs.empty(); } + + ~cdtor_checker() + { + BOOST_TEST(ok()); + } + + void check_in(void * const This) + { + BOOST_TEST(objs.find(This) == objs.end()); + objs.insert(This); + } + + void check_out(void * const This) + { + BOOST_TEST(objs.find(This) != objs.end()); + objs.erase(This); + } +}; +static cdtor_checker mem; + +struct tester +{ + tester(bool throw_except = false) + { + if(throw_except) + { + throw std::logic_error("Deliberate constructor exception"); + } + + mem.check_in(this); + } + + tester(const tester &) + { + mem.check_in(this); + } + + ~tester() + { + mem.check_out(this); + } +}; + +// This is a wrapper around a UserAllocator. It just registers alloc/dealloc +// to/from the system memory. It's used to make sure pool's are allocating +// and deallocating system memory properly. +// Do NOT use this class with static or singleton pools. +template +struct TrackAlloc +{ + typedef typename UserAllocator::size_type size_type; + typedef typename UserAllocator::difference_type difference_type; + + static std::set allocated_blocks; + + static char * malloc(const size_type bytes) + { + char * const ret = UserAllocator::malloc(bytes); + allocated_blocks.insert(ret); + return ret; + } + + static void free(char * const block) + { + BOOST_TEST(allocated_blocks.find(block) != allocated_blocks.end()); + allocated_blocks.erase(block); + UserAllocator::free(block); + } + + static bool ok() + { + return allocated_blocks.empty(); + } +}; +template +std::set TrackAlloc::allocated_blocks; + +typedef TrackAlloc track_alloc; + +void test() +{ + { + // Do nothing pool + boost::object_pool pool; + } + + { + // Construct several tester objects. Don't delete them (i.e., + // test pool's garbage collection). + boost::object_pool pool; + for(int i=0; i < 10; ++i) + { + pool.construct(); + } + } + + { + // Construct several tester objects. Delete some of them. + boost::object_pool pool; + std::vector v; + for(int i=0; i < 10; ++i) + { + v.push_back(pool.construct()); + } + pool_test_random_shuffle(v.begin(), v.end()); + for(int j=0; j < 5; ++j) + { + pool.destroy(v[j]); + } + } + + { + // Test how pool reacts with constructors that throw exceptions. + // Shouldn't have any memory leaks. + boost::object_pool pool; + for(int i=0; i < 5; ++i) + { + pool.construct(); + } + for(int j=0; j < 5; ++j) + { + try + { + // The following constructions will raise an exception. + pool.construct(true); + } + catch(const std::logic_error &) {} + } + } +} + +void test_alloc() +{ + { + // Allocate several tester objects. Delete one. + std::vector > l; + for(int i=0; i < 10; ++i) + { + l.push_back(tester()); + } + l.pop_back(); + } + + { + // Allocate several tester objects. Delete two. + std::deque > l; + for(int i=0; i < 10; ++i) + { + l.push_back(tester()); + } + l.pop_back(); + l.pop_front(); + } + + { + // Allocate several tester objects. Delete two. + std::list > l; + // lists rebind their allocators, so dumping is useless + for(int i=0; i < 10; ++i) + { + l.push_back(tester()); + } + l.pop_back(); + l.pop_front(); + } + + tester * tmp; + { + // Create a memory leak on purpose. (Allocator doesn't have + // garbage collection) + // (Note: memory leak) + boost::pool_allocator a; + tmp = a.allocate(1, 0); + new (tmp) tester(); + } + if(mem.ok()) + { + BOOST_ERROR("Pool allocator cleaned up itself"); + } + // Remove memory checker entry (to avoid error later) and + // clean up memory leak + tmp->~tester(); + boost::pool_allocator::deallocate(tmp, 1); + + // test allocating zero elements + { + boost::pool_allocator alloc; + tester* ip = alloc.allocate(0); + alloc.deallocate(ip, 0); + } +} + +void test_mem_usage() +{ + typedef boost::pool pool_type; + + { + // Constructor should do nothing; no memory allocation + pool_type pool(sizeof(int)); + BOOST_TEST(track_alloc::ok()); + BOOST_TEST(!pool.release_memory()); + BOOST_TEST(!pool.purge_memory()); + + // Should allocate from system + pool.free(pool.malloc()); + BOOST_TEST(!track_alloc::ok()); + + // Ask pool to give up memory it's not using; this should succeed + BOOST_TEST(pool.release_memory()); + BOOST_TEST(track_alloc::ok()); + + // Should allocate from system again + pool.malloc(); // loses the pointer to the returned chunk (*A*) + + // Ask pool to give up memory it's not using; this should fail + BOOST_TEST(!pool.release_memory()); + + // Force pool to give up memory it's not using; this should succeed + // This will clean up the memory leak from (*A*) + BOOST_TEST(pool.purge_memory()); + BOOST_TEST(track_alloc::ok()); + + // Should allocate from system again + pool.malloc(); // loses the pointer to the returned chunk (*B*) + + // pool's destructor should purge the memory + // This will clean up the memory leak from (*B*) + } + + BOOST_TEST(track_alloc::ok()); +} + +void test_void() +{ + typedef boost::pool_allocator void_allocator; + typedef boost::fast_pool_allocator fast_void_allocator; + + typedef void_allocator::rebind::other int_allocator; + typedef fast_void_allocator::rebind::other fast_int_allocator; + + std::vector v1; + std::vector v2; +} + +int main() +{ + std::srand(static_cast(std::time(0))); + + test(); + test_alloc(); + test_mem_usage(); + test_void(); + + return boost::report_errors(); +} diff --git a/src/boost/libs/pool/test/test_simple_seg_storage.cpp b/src/boost/libs/pool/test/test_simple_seg_storage.cpp new file mode 100644 index 000000000..67a33e002 --- /dev/null +++ b/src/boost/libs/pool/test/test_simple_seg_storage.cpp @@ -0,0 +1,304 @@ +/* Copyright (C) 2011 Kwan Ting Chan + * + * Use, modification and distribution is subject to the + * Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) + */ + +#include "test_simple_seg_storage.hpp" +#include "track_allocator.hpp" +#include "random_shuffle.hpp" + +#include +#include +#include +#if defined(BOOST_MSVC) && (BOOST_MSVC <= 1600) +#pragma warning(push) +#pragma warning(disable: 4244) +// ..\..\boost/random/uniform_int_distribution.hpp(171) : +// warning C4127: conditional expression is constant +#pragma warning(disable: 4127) +#endif +#include +#include +#include +#if defined(BOOST_MSVC) && (BOOST_MSVC <= 1600) +#pragma warning(pop) +#endif + +#include + +#include +#include +#include +#include + +#include +#include +#include + +#ifdef BOOST_MSVC +#pragma warning(disable:4267) +#endif + +// "A free list is ordered if repeated calls to malloc() will result in a +// constantly-increasing sequence of values, as determined by std::less" +// Return: true if in constantly-increasing order, false otherwise +bool check_is_order(const std::vector& vs) +{ + if(vs.size() < 2) { return true; } + + void *lower, *higher; + std::vector::const_iterator ci = vs.begin(); + lower = *(ci++); + while(ci != vs.end()) + { + higher = *(ci++); + if(!std::less()(lower, higher)) { return false; } + } + + return true; +} + +// Return: number of chunks malloc'd from store +std::size_t test_is_order(test_simp_seg_store& store) +{ + std::vector vpv; + std::size_t nchunk = 0; + // Pre: !empty() + while(!store.empty()) + { + void* const first = store.get_first(); + void* const pv = store.malloc(); + // "Takes the first available chunk from the free list + // and returns it" + BOOST_TEST(first == pv); + + vpv.push_back(pv); + ++nchunk; + } + BOOST_TEST(check_is_order(vpv)); + + return nchunk; +} + +boost::mt19937 gen; + +int main() +{ + std::srand(static_cast(std::time(0))); + gen.seed(static_cast(std::time(0))); + + /* Store::segregate(block, sz, partition_sz, end) */ + std::size_t partition_sz + = boost::integer::static_lcm::value; + boost::uniform_int<> dist(partition_sz, 10000); + boost::variate_generator > die(gen, dist); + std::size_t block_size = die(); + // Pre: npartition_sz >= sizeof(void*) + // npartition_sz = sizeof(void*) * i, for some integer i + // nsz >= npartition_sz + // block is properly aligned for an array of object of + // size npartition_sz and array of void * + BOOST_ASSERT(partition_sz >= sizeof(void*)); + BOOST_ASSERT(partition_sz % sizeof(void*) == 0); + BOOST_ASSERT(block_size >= partition_sz); + { + char* const pc = track_allocator::malloc(block_size); + // (Test) Pre: block of memory is valid + BOOST_ASSERT(pc); + int endadd = 0; + void* const pvret = test_simp_seg_store::segregate(pc, block_size, + partition_sz, &endadd); + + // The first chunk "is always equal to block" + BOOST_TEST(pvret == pc); + + void* cur = test_simp_seg_store::get_nextof(static_cast(pvret)); + void* last = pvret; + std::size_t nchunk = 1; + while(cur != &endadd) + { + ++nchunk; + + // Memory of each chunk does not overlap + // The free list constructed is actually from the given block + // The "interleaved free list is ordered" + BOOST_TEST(std::less_equal()(static_cast(last) + + partition_sz, cur)); + BOOST_TEST(std::less_equal()(static_cast(cur) + + partition_sz, pc + block_size)); + + last = cur; + cur = test_simp_seg_store::get_nextof(static_cast(cur)); + } + // "The last chunk is set to point to end" + // "Partitioning into as many partition_sz-sized chunks as possible" + BOOST_TEST(nchunk == block_size/partition_sz); + } + + /* t.add_block(block, sz, partition_sz), t.malloc() */ + { + // Default constructor of simple_segregated_storage do nothing + test_simp_seg_store tstore; + // Post: empty() + BOOST_TEST(tstore.empty()); + + char* const pc = track_allocator::malloc(block_size); + tstore.add_block(pc, block_size, partition_sz); + + // The first chunk "is always equal to block" + BOOST_TEST(tstore.get_first() == pc); + + // Empty before add_block() => "is ordered after" + std::size_t nchunk = test_is_order(tstore); + // "Partitioning into as many partition_sz-sized chunks as possible" + BOOST_TEST(nchunk == block_size/partition_sz); + + BOOST_ASSERT(partition_sz <= 23); + test_simp_seg_store tstore2; + char* const pc2 = track_allocator::malloc(88); + tstore2.add_block(pc2, 24, partition_sz); + tstore2.add_block(pc2 + 64, 24, partition_sz); + tstore2.add_block(pc2 + 32, 24, partition_sz); + tstore2.add_block(track_allocator::malloc(23), 23, partition_sz); + std::size_t nchunk_ref = (3*(24/partition_sz)) + (23/partition_sz); + for(nchunk = 0; !tstore2.empty(); tstore2.malloc(), ++nchunk) {} + // add_block() merges new free list to existing + BOOST_TEST(nchunk == nchunk_ref); + } + + /* t.free(chunk) */ + { + test_simp_seg_store tstore; + char* const pc = track_allocator::malloc(partition_sz); + tstore.add_block(pc, partition_sz, partition_sz); + void* pv = tstore.malloc(); + BOOST_TEST(tstore.empty()); + tstore.free(pv); + } + + /* t.add_ordered_block(block, sz, partition_sz) */ + { + { + char* const pc = track_allocator::malloc(6 * partition_sz); + std::vector vpv; + vpv.push_back(pc); + vpv.push_back(pc + (2 * partition_sz)); + vpv.push_back(pc + (4 * partition_sz)); + + do + { + test_simp_seg_store tstore; + tstore.add_ordered_block(vpv[0], 2*partition_sz, partition_sz); + tstore.add_ordered_block(vpv[1], 2*partition_sz, partition_sz); + tstore.add_ordered_block(vpv[2], 2*partition_sz, partition_sz); + // "Order-preserving" + test_is_order(tstore); + } while(std::next_permutation(vpv.begin(), vpv.end())); + } + + { + test_simp_seg_store tstore; + char* const pc = track_allocator::malloc(6 * partition_sz); + tstore.add_ordered_block(pc, 2 * partition_sz, partition_sz); + tstore.add_ordered_block(pc + (4 * partition_sz), + (2 * partition_sz), partition_sz); + // "Order-preserving" + test_is_order(tstore); + } + + { + test_simp_seg_store tstore; + char* const pc = track_allocator::malloc(6 * partition_sz); + tstore.add_ordered_block(pc + (4 * partition_sz), + (2 * partition_sz), partition_sz); + tstore.add_ordered_block(pc, 2 * partition_sz, partition_sz); + // "Order-preserving" + test_is_order(tstore); + } + } + + /* t.ordered_free(chunk) */ + { + char* const pc = track_allocator::malloc(6 * partition_sz); + + test_simp_seg_store tstore; + tstore.add_block(pc, 6 * partition_sz, partition_sz); + + std::vector vpv; + for(std::size_t i=0; i < 6; ++i) { vpv.push_back(tstore.malloc()); } + BOOST_ASSERT(tstore.empty()); + pool_test_random_shuffle(vpv.begin(), vpv.end()); + + for(std::size_t i=0; i < 6; ++i) + { + tstore.ordered_free(vpv[i]); + } + // "Order-preserving" + test_is_order(tstore); + } + + /* t.malloc_n(n, partition_sz) */ + { + { + char* const pc = track_allocator::malloc(12 * partition_sz); + test_simp_seg_store tstore; + tstore.add_ordered_block(pc, 2 * partition_sz, partition_sz); + tstore.add_ordered_block(pc + (3 * partition_sz), + 3 * partition_sz, partition_sz); + tstore.add_ordered_block(pc + (7 * partition_sz), + 5 * partition_sz, partition_sz); + + void* pvret = tstore.malloc_n(6, partition_sz); + BOOST_TEST(pvret == 0); + + pvret = tstore.malloc_n(0, partition_sz); + // There's no prohibition against asking for zero elements + BOOST_TEST(pvret == 0); + + pvret = tstore.malloc_n(3, partition_sz); + // Implicit assumption that contiguous sequence found is the first + // available while traversing from the start of the free list + BOOST_TEST(pvret == pc + (3 * partition_sz)); + + pvret = tstore.malloc_n(4, partition_sz); + BOOST_TEST(pvret == pc + (7 * partition_sz)); + + // There should still be two contiguous + // and one non-contiguous chunk left + std::size_t nchunks = 0; + while(!tstore.empty()) + { + tstore.malloc(); + ++nchunks; + } + BOOST_TEST(nchunks == 3); + } + + { + char* const pc = track_allocator::malloc(12 * partition_sz); + test_simp_seg_store tstore; + tstore.add_ordered_block(pc, 2 * partition_sz, partition_sz); + tstore.add_ordered_block(pc + (3 * partition_sz), + 3 * partition_sz, partition_sz); + tstore.add_ordered_block(pc + (7 * partition_sz), + 5 * partition_sz, partition_sz); + + tstore.malloc_n(3, partition_sz); + // "Order-preserving" + test_is_order(tstore); + } + } + + for(std::set::iterator itr + = track_allocator::allocated_blocks.begin(); + itr != track_allocator::allocated_blocks.end(); + ++itr) + { + delete [] *itr; + } + track_allocator::allocated_blocks.clear(); + return boost::report_errors(); +} diff --git a/src/boost/libs/pool/test/test_simple_seg_storage.hpp b/src/boost/libs/pool/test/test_simple_seg_storage.hpp new file mode 100644 index 000000000..548921bb9 --- /dev/null +++ b/src/boost/libs/pool/test/test_simple_seg_storage.hpp @@ -0,0 +1,173 @@ +/* Copyright (C) 2000, 2001 Stephen Cleary +* Copyright (C) 2011 Kwan Ting Chan +* +* Use, modification and distribution is subject to the +* Boost Software License, Version 1.0. (See accompanying +* file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_POOL_TEST_SIMP_SEG_STORE_HPP +#define BOOST_POOL_TEST_SIMP_SEG_STORE_HPP + +#include +#include + +#include + +#include +#include +#include +#include + +#include + +class test_simp_seg_store : public boost::simple_segregated_storage +{ +private: + // ::first is the address of the start of the added block, + // ::second is the size in bytes of the added block + std::vector > allocated_blocks; + size_type np_sz; + std::set allocated_chunks; + + void set_partition_size(const size_type sz) + { + if(allocated_blocks.empty()) + { + np_sz = sz; + } + else + { + BOOST_ASSERT(np_sz == sz); + } + } + + // Return: true if chunk is from added blocks, false otherwise + bool is_inside_allocated_blocks(void* const chunk) const + { + typedef std::vector >::const_iterator + VPIter; + for(VPIter iter = allocated_blocks.begin(); + iter != allocated_blocks.end(); + ++iter) + { + if( std::less_equal()(iter->first, chunk) + && std::less_equal()(static_cast(chunk) + np_sz, + static_cast(iter->first) + iter->second) ) + { + return true; + } + } + + return false; + } + + void check_in(void* const chunk) + { + // Check that the newly allocated chunk has not already previously + // been allocated, and that the memory does not overlap with + // previously allocated chunks + for(std::set::const_iterator iter = allocated_chunks.begin(); + iter != allocated_chunks.end(); + ++iter) + { + BOOST_TEST( std::less_equal()(static_cast(chunk) + + np_sz, *iter) + || std::less_equal()(static_cast(*iter) + + np_sz, chunk) ); + } + + allocated_chunks.insert(chunk); + } + + void check_out(void* const chunk) + { + BOOST_TEST(allocated_chunks.erase(chunk) == 1); + } + +public: + test_simp_seg_store() + : np_sz(0) {} + + void* get_first() { return first; } + static void*& get_nextof(void* const ptr) { return nextof(ptr); } + + // (Test) Pre: npartition_sz of all added block is the same + // different blocks of memory does not overlap + void add_block(void* const block, + const size_type nsz, const size_type npartition_sz) + { + set_partition_size(npartition_sz); + allocated_blocks.push_back( + std::pair(block, nsz) ); + boost::simple_segregated_storage::add_block( + block, nsz, npartition_sz ); + // Post: !empty() + BOOST_TEST(!empty()); + } + + // (Test) Pre: npartition_sz of all added block is the same + // different blocks of memory does not overlap + void add_ordered_block(void* const block, + const size_type nsz, const size_type npartition_sz) + { + set_partition_size(npartition_sz); + allocated_blocks.push_back( + std::pair(block, nsz) ); + boost::simple_segregated_storage::add_ordered_block( + block, nsz, npartition_sz ); + // Post: !empty() + BOOST_TEST(!empty()); + } + + void* malloc() + { + void* const ret + = boost::simple_segregated_storage::malloc(); + // Chunk returned should actually be from added blocks + BOOST_TEST(is_inside_allocated_blocks(ret)); + check_in(ret); + return ret; + } + + void free(void* const chunk) + { + BOOST_ASSERT(chunk); + check_out(chunk); + boost::simple_segregated_storage::free(chunk); + // Post: !empty() + BOOST_TEST(!empty()); + } + + void ordered_free(void* const chunk) + { + BOOST_ASSERT(chunk); + check_out(chunk); + boost::simple_segregated_storage::ordered_free(chunk); + // Post: !empty() + BOOST_TEST(!empty()); + } + + void* malloc_n(size_type n, size_type partition_size) + { + void* const ret + = boost::simple_segregated_storage::malloc_n( + n, partition_size ); + + if(ret) + { + for(std::size_t i=0; i < n; ++i) + { + void* const chunk = static_cast(ret) + + (i * partition_size); + // Memory returned should actually be from added blocks + BOOST_TEST(is_inside_allocated_blocks(chunk)); + check_in(chunk); + } + } + + return ret; + } +}; + +#endif // BOOST_POOL_TEST_SIMP_SEG_STORE_HPP diff --git a/src/boost/libs/pool/test/test_threading.cpp b/src/boost/libs/pool/test/test_threading.cpp new file mode 100644 index 000000000..f01fea32a --- /dev/null +++ b/src/boost/libs/pool/test/test_threading.cpp @@ -0,0 +1,80 @@ +/* Copyright (C) 2011 John Maddock +* +* Use, modification and distribution is subject to the +* Boost Software License, Version 1.0. (See accompanying +* file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) +*/ + +#include +#include +#include +#if defined(BOOST_MSVC) && (BOOST_MSVC <= 1600) +#pragma warning(push) +#pragma warning(disable: 4244) +// ..\..\boost/random/uniform_int_distribution.hpp(171) : +// warning C4127: conditional expression is constant +#pragma warning(disable: 4127) +// ..\..\boost/random/detail/polynomial.hpp(315) : +// warning C4267: 'argument' : conversion from 'size_t' +// to 'int', possible loss of data +#pragma warning(disable: 4267) +#endif +#include +#include +#if defined(BOOST_MSVC) && (BOOST_MSVC <= 1600) +#pragma warning(pop) +#endif + +void run_tests() +{ + boost::random::mt19937 gen; + boost::random::uniform_int_distribution<> dist(-10, 10); + std::list > l; + + for(int i = 0; i < 100; ++i) + l.push_back(i); + + for(int i = 0; i < 20000; ++i) + { + int val = dist(gen); + if(val < 0) + { + while(val && l.size()) + { + l.pop_back(); + ++val; + } + } + else + { + while(val) + { + l.push_back(val); + --val; + } + } + } +} + +int main() +{ + std::list > threads; + for(int i = 0; i < 10; ++i) + { + try{ + threads.push_back(boost::shared_ptr(new boost::thread(&run_tests))); + } + catch(const std::exception& e) + { + std::cerr << "Thread creation failed with message: " << e.what() << "" << std::endl; + } + } + std::list >::const_iterator a(threads.begin()), b(threads.end()); + while(a != b) + { + (*a)->join(); + ++a; + } + return 0; +} + diff --git a/src/boost/libs/pool/test/test_valgrind_fail_1.cpp b/src/boost/libs/pool/test/test_valgrind_fail_1.cpp new file mode 100644 index 000000000..43e749742 --- /dev/null +++ b/src/boost/libs/pool/test/test_valgrind_fail_1.cpp @@ -0,0 +1,22 @@ +/* Copyright (C) 2011 John Maddock +* +* Use, modification and distribution is subject to the +* Boost Software License, Version 1.0. (See accompanying +* file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) +*/ + +// Test of bug #2656 (https://svn.boost.org/trac/boost/ticket/2656) + +#include +#include +#include + +static const int magic_value = 0x12345678; + +int main() +{ + boost::pool<> p(sizeof(int)); + int* ptr = static_cast((p.malloc)()); + std::cout << *ptr << std::endl; // uninitialized read + return 0; +} diff --git a/src/boost/libs/pool/test/test_valgrind_fail_2.cpp b/src/boost/libs/pool/test/test_valgrind_fail_2.cpp new file mode 100644 index 000000000..84b703b7b --- /dev/null +++ b/src/boost/libs/pool/test/test_valgrind_fail_2.cpp @@ -0,0 +1,20 @@ +/* Copyright (C) 2011 John Maddock +* +* Use, modification and distribution is subject to the +* Boost Software License, Version 1.0. (See accompanying +* file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) +*/ + +// Test of bug #2656 (https://svn.boost.org/trac/boost/ticket/2656) + +#include + +int main() +{ + boost::pool<> p(sizeof(int)); + int* ptr = static_cast((p.malloc)()); + *ptr = 0; + (p.free)(ptr); + *ptr = 2; // write to freed memory + return 0; +} diff --git a/src/boost/libs/pool/test/track_allocator.hpp b/src/boost/libs/pool/test/track_allocator.hpp new file mode 100644 index 000000000..ed989f048 --- /dev/null +++ b/src/boost/libs/pool/test/track_allocator.hpp @@ -0,0 +1,104 @@ +/* Copyright (C) 2000, 2001 Stephen Cleary +* Copyright (C) 2011 Kwan Ting Chan +* +* Use, modification and distribution is subject to the +* Boost Software License, Version 1.0. (See accompanying +* file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) +*/ + +#ifndef BOOST_POOL_TRACK_ALLOCATOR_HPP +#define BOOST_POOL_TRACK_ALLOCATOR_HPP + +#include + +#include +#include +#include + +#include + +// Each "tester" object below checks into and out of the "cdtor_checker", +// which will check for any problems related to the construction/destruction of +// "tester" objects. +class cdtor_checker +{ +private: + // Each constructed object registers its "this" pointer into "objs" + std::set objs; + +public: + // True iff all objects that have checked in have checked out + bool ok() const { return objs.empty(); } + + ~cdtor_checker() + { + BOOST_TEST(ok()); + } + + void check_in(void * const This) + { + BOOST_TEST(objs.find(This) == objs.end()); + objs.insert(This); + } + + void check_out(void * const This) + { + BOOST_TEST(objs.find(This) != objs.end()); + objs.erase(This); + } +}; +static cdtor_checker mem; + +struct tester +{ + tester(bool throw_except = false) + { + if(throw_except) + { + throw std::logic_error("Deliberate constructor exception"); + } + + mem.check_in(this); + } + + tester(const tester &) + { + mem.check_in(this); + } + + ~tester() + { + mem.check_out(this); + } +}; + +// Allocator that registers alloc/dealloc to/from the system memory +struct track_allocator +{ + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + + static std::set allocated_blocks; + + static char* malloc(const size_type bytes) + { + char* const ret = new (std::nothrow) char[bytes]; + allocated_blocks.insert(ret); + return ret; + } + + static void free(char* const block) + { + BOOST_TEST(allocated_blocks.find(block) != allocated_blocks.end()); + allocated_blocks.erase(block); + delete [] block; + } + + static bool ok() + { + return allocated_blocks.empty(); + } +}; +std::set track_allocator::allocated_blocks; + +#endif // BOOST_POOL_TRACK_ALLOCATOR_HPP diff --git a/src/boost/libs/pool/test/valgrind_config_check.cpp b/src/boost/libs/pool/test/valgrind_config_check.cpp new file mode 100644 index 000000000..35252eefa --- /dev/null +++ b/src/boost/libs/pool/test/valgrind_config_check.cpp @@ -0,0 +1,7 @@ + +#include + +int main() +{ + return 0; +} \ No newline at end of file -- cgit v1.2.3