Index: src/simutrans/obj/baum.cc
===================================================================
--- src/simutrans/obj/baum.cc	(revision 10635)
+++ src/simutrans/obj/baum.cc	(working copy)
@@ -28,6 +28,7 @@
 
 FLAGGED_PIXVAL baum_t::outline_color = 0;
 
+freelist_tpl<baum_t> baum_t::fl;
 
 baum_t::baum_t(loadsave_t *file) :
 	obj_t(),
@@ -323,15 +324,3 @@
 {
 	return (welt->get_current_month() - (uint32)geburt) % (1<<12);
 }
-
-
-void *baum_t::operator new(size_t /*s*/)
-{
-	return freelist_t::gimme_node(sizeof(baum_t));
-}
-
-
-void baum_t::operator delete(void *p)
-{
-	freelist_t::putback_node(sizeof(baum_t),p);
-}
Index: src/simutrans/obj/baum.h
===================================================================
--- src/simutrans/obj/baum.h	(revision 10635)
+++ src/simutrans/obj/baum.h	(working copy)
@@ -13,6 +13,7 @@
 #include "../tpl/stringhashtable_tpl.h"
 #include "../tpl/vector_tpl.h"
 #include "../tpl/weighted_vector_tpl.h"
+#include "../tpl/freelist_tpl.h"
 #include "../descriptor/tree_desc.h"
 #include "../simcolor.h"
 #include "../dataobj/environment.h"
@@ -48,6 +49,8 @@
 
 	// one bit free ;)
 
+	static freelist_tpl<baum_t> fl;
+
 public:
 	/// Only the load save constructor should be called outside.
 	/// Otherwise I suggest use the plant tree function (@see tree_builder_t)
@@ -59,6 +62,9 @@
 
 	baum_t(koord3d pos, const tree_desc_t *desc);
 
+	void* operator new(size_t) { return fl.gimme_node(); }
+	void operator delete(void* p) { return fl.putback_node(p); }
+
 public:
 	/// @copydoc obj_t::get_name
 	const char *get_name() const OVERRIDE { return "Baum"; }
@@ -115,10 +121,6 @@
 	/// @returns age of the tree in months, between 0 and 4095
 	uint16 get_age() const;
 
-public:
-	void *operator new(size_t s);
-	void operator delete(void *p);
-
 private:
 	/// calculate offsets for new trees
 	void calc_off(slope_t::type slope, sint8 x=-128, sint8 y=-128);
Index: src/simutrans/obj/wolke.cc
===================================================================
--- src/simutrans/obj/wolke.cc	(revision 10635)
+++ src/simutrans/obj/wolke.cc	(working copy)
@@ -18,9 +18,10 @@
 
 #include "../tpl/vector_tpl.h"
 
-
 vector_tpl<const skin_desc_t *>wolke_t::all_clouds(0);
 
+freelist_tpl<wolke_t> wolke_t::fl;
+
 bool wolke_t::register_desc(const skin_desc_t* desc)
 {
 	// avoid duplicates with same name
@@ -34,19 +35,6 @@
 }
 
 
-void *wolke_t::operator new(size_t /*s*/)
-{
-	return freelist_t::gimme_node(sizeof(wolke_t));
-}
-
-
-void wolke_t::operator delete(void *p)
-{
-	freelist_t::putback_node(sizeof(wolke_t),p);
-}
-
-
-
 wolke_t::wolke_t(koord3d pos, sint8 b_x_off, sint8 b_y_off, sint16 b_h_off, uint16 lt, uint16 ul, const skin_desc_t* desc ) :
 	obj_no_info_t(pos)
 {
Index: src/simutrans/obj/wolke.h
===================================================================
--- src/simutrans/obj/wolke.h	(revision 10635)
+++ src/simutrans/obj/wolke.h	(working copy)
@@ -14,6 +14,7 @@
 #include "../tpl/vector_tpl.h"
 #include "../display/simimg.h"
 
+#include "../tpl/freelist_tpl.h"
 
 class karte_t;
 
@@ -37,11 +38,13 @@
 
 	sint16 calc_yoff() const; // calculate the smoke height using uplift and insta_zeit
 
+	static freelist_tpl<wolke_t> fl; // if not declared static, it would consume 4 bytes due to empty class nonzero rules
+
 public:
 	static bool register_desc(const skin_desc_t *desc);
 
-	void * operator new(size_t s);
-	void operator delete(void *p);
+	void* operator new(size_t) { return fl.gimme_node(); }
+	void operator delete(void* p) { return fl.putback_node(p); }
 
 	wolke_t(loadsave_t *file);
 	wolke_t(koord3d pos, sint8 xoff, sint8 yoff, sint16 hoff, uint16 lifetime, uint16 uplift, const skin_desc_t *cloud );
Index: src/simutrans/tpl/freelist_tpl.h
===================================================================
--- src/simutrans/tpl/freelist_tpl.h	(nonexistent)
+++ src/simutrans/tpl/freelist_tpl.h	(working copy)
@@ -0,0 +1,169 @@
+/*
+ * This file is part of the Simutrans project under the Artistic License.
+ * (see LICENSE.txt)
+ */
+
+#ifndef TPL_FREELIST_TPL_H
+#define TPL_FREELIST_TPL_H
+
+struct nodelist_node_t
+{
+#ifdef DEBUG_FREELIST
+	unsigned magic : 15;
+	unsigned free : 1;
+#endif
+	nodelist_node_t* next;
+};
+
+#include <typeinfo>
+
+#include "../simmem.h"
+
+#ifdef MULTI_THREADx
+#include "../utils/simthread.h"
+#endif
+
+
+/**
+  * A template class for const sized memory pool
+  * Must be a static member! Does not use exceptions
+  */
+template<class T> class freelist_tpl
+{
+private:
+	// next free node (or NULL)
+	nodelist_node_t* freelist;
+
+	// number of currently allocated node
+	size_t nodecount;
+
+	// list of all allocated memory
+	nodelist_node_t* chunk_list;
+
+	const size_t new_chuck_size = (32768 - sizeof(void*)) / sizeof(T);
+
+#ifdef MULTI_THREADx
+	pthread_mutex_t freelist_mutex = PTHREAD_MUTEX_INITIALIZER;;
+#endif
+
+public:
+	freelist_tpl() : freelist(0), nodecount(0), chunk_list(0) {}
+
+	freelist_tpl(size_t ncs) : freelist(0), nodecount(0), chunk_list(0), new_chuck_size(ncs) {}
+
+	void *gimme_node()
+	{
+#ifdef MULTI_THREADx
+		pthread_mutex_lock(&freelist_mutex);
+#endif
+		nodelist_node_t *tmp;
+		if (freelist == NULL) {
+			int chunksize = 0x1000;
+			char* p = (char*)xmalloc(chunksize *sizeof(T) + sizeof(nodelist_node_t));
+
+#ifdef USE_VALGRIND_MEMCHECK
+			// tell valgrind that we still cannot access the pool p
+			VALGRIND_MAKE_MEM_NOACCESS(p, chunksize *sizeof(T) + sizeof(nodelist_node_t));
+#endif
+			// put the memory into the chunklist for free it
+			nodelist_node_t* chunk = (nodelist_node_t *)p;
+
+#ifdef USE_VALGRIND_MEMCHECK
+			// tell valgrind that we reserved space for one nodelist_node_t
+			VALGRIND_CREATE_MEMPOOL(chunk, 0, false);
+			VALGRIND_MEMPOOL_ALLOC(chunk, chunk, sizeof(*chunk));
+			VALGRIND_MAKE_MEM_UNDEFINED(chunk, sizeof(*chunk));
+#endif
+			chunk->next = chunk_list;
+			chunk_list = chunk;
+			p += sizeof(nodelist_node_t);
+			// then enter nodes into nodelist
+			for (int i = 0; i < chunksize; i++) {
+				nodelist_node_t* tmp = (nodelist_node_t*)(p + i * sizeof(T));
+#ifdef USE_VALGRIND_MEMCHECK
+				// tell valgrind that we reserved space for one nodelist_node_t
+				VALGRIND_CREATE_MEMPOOL(tmp, 0, false);
+				VALGRIND_MEMPOOL_ALLOC(tmp, tmp, sizeof(*tmp));
+				VALGRIND_MAKE_MEM_UNDEFINED(tmp, sizeof(*tmp));
+#endif
+				tmp->next = freelist;
+				freelist = tmp;
+			}
+		}
+
+		// return first node of list
+		tmp = freelist;
+		freelist = tmp->next;
+
+#ifdef MULTI_THREADx
+		pthread_mutex_unlock(&freelist_mutex);
+#endif
+
+#ifdef USE_VALGRIND_MEMCHECK
+		// tell valgrind that we now have access to a chunk of size bytes
+		VALGRIND_MEMPOOL_CHANGE(tmp, tmp, tmp, sizeof(T));
+		VALGRIND_MAKE_MEM_UNDEFINED(tmp, sizeof(T));
+#endif
+
+#ifdef DEBUG_FREELIST
+		tmp->magic = 0x5555;
+		tmp->free = 0;
+#endif
+		nodecount++;
+
+		return (void *)(&(tmp->next));
+	}
+
+	// clears all list memories
+	void free_all_nodes()
+	{
+		while (chunk_list) {
+			nodelist_node_t* p = chunk_list;
+			chunk_list = chunk_list->next;
+
+			// now release memory
+#ifdef USE_VALGRIND_MEMCHECK
+			VALGRIND_DESTROY_MEMPOOL(p);
+#endif
+			free(p);
+		}
+		freelist = 0;
+		nodecount = 0;
+	}
+
+	void putback_node(void* p)
+	{
+#ifdef USE_VALGRIND_MEMCHECK
+		// tell valgrind that we keep access to a nodelist_node_t within the memory chunk
+		VALGRIND_MEMPOOL_CHANGE(p, p, p, sizeof(nodelist_node_t));
+		VALGRIND_MAKE_MEM_NOACCESS(p, size);
+		VALGRIND_MAKE_MEM_UNDEFINED(p, sizeof(nodelist_node_t));
+#endif
+
+#ifdef MULTI_THREADx
+		pthread_mutex_unlock(&freelist_mutex);
+#endif
+
+		// putback to first node
+		nodelist_node_t* tmp = (nodelist_node_t*)p;
+#ifdef DEBUG_FREELIST
+		tmp = (nodelist_node_t*)((char*)p - min_size);
+		assert(tmp->magic == 0x5555 && tmp->free == 0 && tmp->size == size / 4);
+		tmp->free = 1;
+#endif
+		tmp->next = freelist;
+		freelist = tmp;
+
+		nodecount--;
+
+		if (nodecount == 0) {
+			free_all_nodes();
+		}
+#ifdef MULTI_THREADx
+		pthread_mutex_unlock(&freelist_mutex);
+#endif
+	}
+
+};
+
+#endif

Property changes on: src/simutrans/tpl/freelist_tpl.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Index: src/simutrans/vehicle/pedestrian.cc
===================================================================
--- src/simutrans/vehicle/pedestrian.cc	(revision 10635)
+++ src/simutrans/vehicle/pedestrian.cc	(working copy)
@@ -21,6 +21,8 @@
 #include <cstdio>
 
 
+freelist_tpl<pedestrian_t> pedestrian_t::fl;
+
 static uint32 const strecke[] = { 6000, 11000, 15000, 20000, 25000, 30000, 35000, 40000 };
 
 static weighted_vector_tpl<const pedestrian_desc_t*> list_timeline;
@@ -382,15 +384,3 @@
 		buf.printf(translator::translate("Constructed by %s"), maker);
 	}
 }
-
-
-void *pedestrian_t::operator new(size_t /*s*/)
-{
-	return freelist_t::gimme_node(sizeof(pedestrian_t));
-}
-
-
-void pedestrian_t::operator delete(void *p)
-{
-	freelist_t::putback_node(sizeof(pedestrian_t),p);
-}
Index: src/simutrans/vehicle/pedestrian.h
===================================================================
--- src/simutrans/vehicle/pedestrian.h	(revision 10635)
+++ src/simutrans/vehicle/pedestrian.h	(working copy)
@@ -8,6 +8,7 @@
 
 
 #include "simroadtraffic.h"
+#include "../tpl/freelist_tpl.h"
 
 
 class pedestrian_desc_t;
@@ -32,6 +33,8 @@
 
 	bool list_empty();
 
+	static freelist_tpl<pedestrian_t> fl; // if not declared static, it would consume 4 bytes due to empty class nonzero rules
+
 protected:
 	void rdwr(loadsave_t *file) OVERRIDE;
 
@@ -72,8 +75,8 @@
 	grund_t* hop_check() OVERRIDE;
 	void hop(grund_t* gr) OVERRIDE;
 
-	void * operator new(size_t s);
-	void operator delete(void *p);
+	void* operator new(size_t) { return fl.gimme_node(); }
+	void operator delete(void* p) { return fl.putback_node(p); }
 
 	// class register functions
 	static bool register_desc(const pedestrian_desc_t *desc);
