From 06f9c019864a0fd3f832d42101897fee8c27a7cb Mon Sep 17 00:00:00 2001 From: Jonathan G Rennison Date: Tue, 27 Sep 2016 01:05:42 +0100 Subject: [PATCH 1/5] Fix CPU pointer width detection in configure script. --- config.lib | 40 ++++++++++++++++++++++++++++------------ 1 file changed, 28 insertions(+), 12 deletions(-) diff --git a/config.lib b/config.lib index ae9b5be2c1..91b710252a 100644 --- a/config.lib +++ b/config.lib @@ -3123,24 +3123,40 @@ detect_nforenum() { log 1 "checking nforenum... found" } -detect_cputype() { - if [ -n "$cpu_type" ] && [ "$cpu_type" != "DETECT" ]; then - log 1 "forcing cpu-type... $cpu_type bits" - return; - fi - echo "#define _SQ64 1" > tmp.64bit.cpp - echo "#include \"src/stdafx.h\"" >> tmp.64bit.cpp - echo "assert_compile(sizeof(size_t) == 8);" >> tmp.64bit.cpp - echo "int main() { return 0; }" >> tmp.64bit.cpp - execute="$cxx_host $CFLAGS tmp.64bit.cpp -o tmp.64bit -DTESTING 2>&1" +_detect_cputype_width() { + echo "#define _SQ64 1" > $1.cpp + echo "#include \"src/stdafx.h\"" >> $1.cpp + echo "assert_compile(sizeof(size_t) == $2);" >> $1.cpp + echo "int main() { return 0; }" >> $1.cpp + execute="$cxx_host $CFLAGS -std=c++11 $1.cpp -o $1 -DTESTING 2>&1" cpu_type="`eval $execute 2>/dev/null`" ret=$? log 2 "executing $execute" log 2 " returned $cpu_type" log 2 " exit code $ret" - if [ "$ret" = "0" ]; then cpu_type="64"; else cpu_type="32"; fi + rm -f $1 $1.cpp + return $ret +} + +detect_cputype() { + if [ -n "$cpu_type" ] && [ "$cpu_type" != "DETECT" ]; then + log 1 "forcing cpu-type... $cpu_type bits" + return; + fi + _detect_cputype_width tmp.32bit 4 + result32=$? + _detect_cputype_width tmp.64bit 8 + result64=$? + + if [ "$result32" = 0 ] && [ "$result64" != 0 ]; then + cpu_type="32" + elif [ "$result32" != 0 ] && [ "$result64" = 0 ]; then + cpu_type="64" + else + log 1 "configure: unable to determine cpu-type (pointer width)" + exit 1 + fi log 1 "detecting cpu-type... $cpu_type bits" - rm -f tmp.64bit tmp.64bit.cpp } detect_sse_capable_architecture() { From 8f3e0c4fe5e3f0f609eccdbf9451bc381b0abd6b Mon Sep 17 00:00:00 2001 From: Jonathan G Rennison Date: Wed, 8 Feb 2017 21:46:50 +0000 Subject: [PATCH 2/5] Add a custom arena allocator utility. --- projects/openttd_vs100.vcxproj | 2 + projects/openttd_vs100.vcxproj.filters | 6 ++ projects/openttd_vs140.vcxproj | 2 + projects/openttd_vs140.vcxproj.filters | 6 ++ projects/openttd_vs80.vcproj | 8 +++ projects/openttd_vs90.vcproj | 8 +++ source.list | 1 + src/core/dyn_arena_alloc.hpp | 97 ++++++++++++++++++++++++++ 8 files changed, 130 insertions(+) create mode 100644 src/core/dyn_arena_alloc.hpp diff --git a/projects/openttd_vs100.vcxproj b/projects/openttd_vs100.vcxproj index a7abe4d1ab..00c6f66811 100644 --- a/projects/openttd_vs100.vcxproj +++ b/projects/openttd_vs100.vcxproj @@ -667,6 +667,8 @@ + + diff --git a/projects/openttd_vs100.vcxproj.filters b/projects/openttd_vs100.vcxproj.filters index d996963c06..54cd94e730 100644 --- a/projects/openttd_vs100.vcxproj.filters +++ b/projects/openttd_vs100.vcxproj.filters @@ -1230,6 +1230,12 @@ Core Source Code + + Core Source Code + + + Core Source Code + Core Source Code diff --git a/projects/openttd_vs140.vcxproj b/projects/openttd_vs140.vcxproj index 67acda0402..19760f468b 100644 --- a/projects/openttd_vs140.vcxproj +++ b/projects/openttd_vs140.vcxproj @@ -684,6 +684,8 @@ + + diff --git a/projects/openttd_vs140.vcxproj.filters b/projects/openttd_vs140.vcxproj.filters index d996963c06..54cd94e730 100644 --- a/projects/openttd_vs140.vcxproj.filters +++ b/projects/openttd_vs140.vcxproj.filters @@ -1230,6 +1230,12 @@ Core Source Code + + Core Source Code + + + Core Source Code + Core Source Code diff --git a/projects/openttd_vs80.vcproj b/projects/openttd_vs80.vcproj index fcd9c0e3a3..afb125acf2 100644 --- a/projects/openttd_vs80.vcproj +++ b/projects/openttd_vs80.vcproj @@ -1946,6 +1946,14 @@ RelativePath=".\..\src\core\bitmath_func.hpp" > + + + + diff --git a/projects/openttd_vs90.vcproj b/projects/openttd_vs90.vcproj index cd5eea9d4e..f35a14ece5 100644 --- a/projects/openttd_vs90.vcproj +++ b/projects/openttd_vs90.vcproj @@ -1943,6 +1943,14 @@ RelativePath=".\..\src\core\bitmath_func.hpp" > + + + + diff --git a/source.list b/source.list index b2c2f4d495..c88f322cd1 100644 --- a/source.list +++ b/source.list @@ -424,6 +424,7 @@ core/backup_type.hpp core/bitmath_func.cpp core/bitmath_func.hpp core/container_func.hpp +core/dyn_arena_alloc.hpp core/endian_func.hpp core/endian_type.hpp core/enum_type.hpp diff --git a/src/core/dyn_arena_alloc.hpp b/src/core/dyn_arena_alloc.hpp new file mode 100644 index 0000000000..2bc4978d14 --- /dev/null +++ b/src/core/dyn_arena_alloc.hpp @@ -0,0 +1,97 @@ +/* $Id$ */ + +/* + * This file is part of OpenTTD. + * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. + * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . + */ + +/** @file dyn_arena_alloc.hpp Dynamic chunk-size arena allocator. */ + +#include + +/** + * Custom arena allocator for uniform-size allocations of a variable size. + * The allocation and chunk sizes may only be changed when the arena is empty. + */ +class DynUniformArenaAllocator { + std::vector used_blocks; + + void *current_block = nullptr; + void *last_freed = nullptr; + size_t next_position = 0; + + size_t item_size = 0; + size_t items_per_chunk = 0; + + void NewBlock() + { + current_block = malloc(item_size * items_per_chunk); + assert(current_block != nullptr); + next_position = 0; + used_blocks.push_back(current_block); + } + + public: + DynUniformArenaAllocator() = default; + DynUniformArenaAllocator(const DynUniformArenaAllocator &other) = delete; + DynUniformArenaAllocator& operator=(const DynUniformArenaAllocator &other) = delete; + + ~DynUniformArenaAllocator() + { + EmptyArena(); + } + + void EmptyArena() + { + current_block = nullptr; + last_freed = nullptr; + next_position = 0; + for (void *block : used_blocks) { + free(block); + } + used_blocks.clear(); + } + + void ResetArena() + { + EmptyArena(); + item_size = 0; + items_per_chunk = 0; + } + + void *Allocate() { + assert(item_size != 0); + if (last_freed) { + void *ptr = last_freed; + last_freed = *reinterpret_cast(ptr); + return ptr; + } else { + if (current_block == nullptr || next_position == items_per_chunk) { + NewBlock(); + } + void *out = reinterpret_cast(current_block) + (item_size * next_position); + next_position++; + return out; + } + } + + void Free(void *ptr) { + if (!ptr) return; + assert(current_block != nullptr); + + *reinterpret_cast(ptr) = last_freed; + last_freed = ptr; + } + + void SetParameters(size_t item_size, size_t items_per_chunk) + { + if (item_size < sizeof(void *)) item_size = sizeof(void *); + if (this->item_size == item_size && this->items_per_chunk == items_per_chunk) return; + + assert(current_block == nullptr); + this->item_size = item_size; + this->items_per_chunk = items_per_chunk; + } +}; From 2fb822d392fba9198b121841a508d1b75f6d5e74 Mon Sep 17 00:00:00 2001 From: Jonathan G Rennison Date: Wed, 29 Mar 2017 19:39:55 +0100 Subject: [PATCH 3/5] Fix includes and header guards of container functions. --- src/core/container_func.hpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/core/container_func.hpp b/src/core/container_func.hpp index 1b8e8ad847..276c1f7f54 100644 --- a/src/core/container_func.hpp +++ b/src/core/container_func.hpp @@ -9,6 +9,11 @@ /** @file container_func.hpp Functions related to use of containers. */ +#ifndef CONTAINER_FUNC_HPP +#define CONTAINER_FUNC_HPP + +#include + template unsigned int container_unordered_remove_if (C &container, UP predicate) { unsigned int removecount = 0; for (auto it = container.begin(); it != container.end();) { @@ -33,3 +38,5 @@ template unsigned int container_unordered_remove(C &con return v == value; }); } + +#endif /* CONTAINER_FUNC_HPP */ From a3034891a1930fa0a2434eef09ffa02ef34fcc93 Mon Sep 17 00:00:00 2001 From: Jonathan G Rennison Date: Wed, 29 Mar 2017 19:46:30 +0100 Subject: [PATCH 4/5] Add missing include guard for dyn arena alloc header. --- src/core/dyn_arena_alloc.hpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/core/dyn_arena_alloc.hpp b/src/core/dyn_arena_alloc.hpp index 2bc4978d14..2a074d6aa1 100644 --- a/src/core/dyn_arena_alloc.hpp +++ b/src/core/dyn_arena_alloc.hpp @@ -9,6 +9,9 @@ /** @file dyn_arena_alloc.hpp Dynamic chunk-size arena allocator. */ +#ifndef DYN_ARENA_ALLOC_HPP +#define DYN_ARENA_ALLOC_HPP + #include /** @@ -95,3 +98,5 @@ class DynUniformArenaAllocator { this->items_per_chunk = items_per_chunk; } }; + +#endif /* DYN_ARENA_ALLOC_HPP */ From 4e9d4dd80adc4cbe9e06016c10535f4f0fea2bc6 Mon Sep 17 00:00:00 2001 From: Jonathan G Rennison Date: Sat, 4 Mar 2017 23:39:27 +0000 Subject: [PATCH 5/5] Add a PreCleanPool() static method to pool item types. (cherry picked from commit 87142ed840bb76361bc7a7219d643e49358487dd) --- src/core/pool_func.hpp | 1 + src/core/pool_type.hpp | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/src/core/pool_func.hpp b/src/core/pool_func.hpp index 5569addbd7..a5375e13fc 100644 --- a/src/core/pool_func.hpp +++ b/src/core/pool_func.hpp @@ -196,6 +196,7 @@ DEFINE_POOL_METHOD(void)::FreeItem(size_t index) DEFINE_POOL_METHOD(void)::CleanPool() { this->cleaning = true; + Titem::PreCleanPool(); for (size_t i = 0; i < this->first_unused; i++) { delete this->Get(i); // 'delete NULL;' is very valid } diff --git a/src/core/pool_type.hpp b/src/core/pool_type.hpp index 4d20ed1abb..70f6480103 100644 --- a/src/core/pool_type.hpp +++ b/src/core/pool_type.hpp @@ -286,6 +286,13 @@ struct Pool : PoolBase { * @note it's called only when !CleaningPool() */ static inline void PostDestructor(size_t index) { } + + /** + * Dummy function called before a pool is about to be cleaned. + * If you want to use it, override it in PoolItem's subclass. + * @note it's called only when CleaningPool() + */ + static inline void PreCleanPool() { } }; private: