Index: src/simutrans/obj/wolke.cc
===================================================================
--- src/simutrans/obj/wolke.cc	(revision 10633)
+++ src/simutrans/obj/wolke.cc	(working copy)
@@ -18,7 +18,6 @@
 
 #include "../tpl/vector_tpl.h"
 
-
 vector_tpl<const skin_desc_t *>wolke_t::all_clouds(0);
 
 bool wolke_t::register_desc(const skin_desc_t* desc)
@@ -34,19 +33,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 10633)
+++ 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
 
+	freelist_tpl<wolke_t> fl;
+
 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 freelist_tpl<wolke_t>::gimme_node(); }
+	void operator delete(void* p) { return freelist_tpl<wolke_t>::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,148 @@
+/*
+ * 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 "../simdebug.h"
+#include "../simmem.h"
+//#include "../simtypes.h"
+
+/**
+  * A template class for bounds checked 1-dimensional arrays.
+  * This is kept as simple as possible. Does not use exceptions
+  * for error handling.
+  */
+template<class T> class freelist_tpl
+{
+private:
+	// next free node (or NULL)
+	static nodelist_node_t* freelist;
+
+	// number of currently allocated node
+	static size_t nodecount;
+
+	// list of all allocated memory
+	static nodelist_node_t* chunk_list;
+
+
+public:
+	static void *gimme_node()
+	{
+		nodelist_node_t *tmp;
+		if (freelist == NULL) {
+			int num_elements = 0x1000;
+			char* p = (char*)xmalloc(num_elements*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, num_elements*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 < num_elements; 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 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
+	static 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;
+	}
+
+	static 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
+
+		// 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();
+		}
+	}
+
+};
+
+template<typename T> nodelist_node_t * freelist_tpl<T>::freelist = 0;
+template<typename T> nodelist_node_t * freelist_tpl<T>::chunk_list = 0;
+template<typename T> size_t freelist_tpl<T>::nodecount = 0;
+
+#endif

Property changes on: src/simutrans/tpl/freelist_tpl.h
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property

