--- deliantra/server/include/util.h 2007/07/11 12:29:06 1.52 +++ deliantra/server/include/util.h 2008/01/22 15:53:01 1.60 @@ -1,9 +1,9 @@ /* - * This file is part of Crossfire TRT, the Roguelike Realtime MORPG. + * This file is part of Deliantra, the Roguelike Realtime MMORPG. * - * Copyright (©) 2005,2006,2007 Marc Alexander Lehmann / Robin Redeker / the Crossfire TRT team + * Copyright (©) 2005,2006,2007 Marc Alexander Lehmann / Robin Redeker / the Deliantra team * - * Crossfire TRT is free software: you can redistribute it and/or modify + * Deliantra 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, either version 3 of the License, or * (at your option) any later version. @@ -16,13 +16,14 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . * - * The authors can be reached via e-mail to + * The authors can be reached via e-mail to */ #ifndef UTIL_H__ #define UTIL_H__ //#define PREFER_MALLOC +#define DEBUG_SALLOC #if __GNUC__ >= 3 # define is_constant(c) __builtin_constant_p (c) @@ -54,6 +55,15 @@ #include #include +#ifdef DEBUG_SALLOC +# define g_slice_alloc0(s) debug_slice_alloc0(s) +# define g_slice_alloc(s) debug_slice_alloc(s) +# define g_slice_free1(s,p) debug_slice_free1(s,p) +void *g_slice_alloc (unsigned long size); +void *g_slice_alloc0 (unsigned long size); +void g_slice_free1 (unsigned long size, void *ptr); +#endif + // use C0X decltype for auto declarations until ISO C++ sanctifies them (if ever) #define auto(var,expr) decltype(expr) var = (expr) @@ -174,6 +184,8 @@ return ((d - 1) & 7) + 1; } +extern size_t slice_alloc; // statistics + // makes dynamically allocated objects zero-initialised struct zero_initialised { @@ -185,21 +197,25 @@ void *operator new (size_t s) { + slice_alloc += s; return g_slice_alloc0 (s); } void *operator new[] (size_t s) { + slice_alloc += s; return g_slice_alloc0 (s); } void operator delete (void *p, size_t s) { + slice_alloc -= s; g_slice_free1 (s, p); } void operator delete[] (void *p, size_t s) { + slice_alloc -= s; g_slice_free1 (s, p); } }; @@ -227,6 +243,7 @@ #ifdef PREFER_MALLOC free (ptr); #else + slice_alloc -= n * sizeof (T); g_slice_free1 (n * sizeof (T), (void *)ptr); #endif } @@ -335,33 +352,67 @@ extern rand_gen rndm; +INTERFACE_CLASS (attachable) +struct refcnt_base +{ + typedef int refcnt_t; + mutable refcnt_t ACC (RW, refcnt); + + MTH void refcnt_inc () const { ++refcnt; } + MTH void refcnt_dec () const { --refcnt; } + + refcnt_base () : refcnt (0) { } +}; + +// to avoid branches with more advanced compilers +extern refcnt_base::refcnt_t refcnt_dummy; + template struct refptr { + // p if not null + refcnt_base::refcnt_t *refcnt_ref () { return p ? &p->refcnt : &refcnt_dummy; } + + void refcnt_dec () + { + if (!is_constant (p)) + --*refcnt_ref (); + else if (p) + --p->refcnt; + } + + void refcnt_inc () + { + if (!is_constant (p)) + ++*refcnt_ref (); + else if (p) + ++p->refcnt; + } + T *p; refptr () : p(0) { } - refptr (const refptr &p) : p(p.p) { if (p) p->refcnt_inc (); } - refptr (T *p) : p(p) { if (p) p->refcnt_inc (); } - ~refptr () { if (p) p->refcnt_dec (); } + refptr (const refptr &p) : p(p.p) { refcnt_inc (); } + refptr (T *p) : p(p) { refcnt_inc (); } + ~refptr () { refcnt_dec (); } const refptr &operator =(T *o) { - if (p) p->refcnt_dec (); + // if decrementing ever destroys we need to reverse the order here + refcnt_dec (); p = o; - if (p) p->refcnt_inc (); - + refcnt_inc (); return *this; } - const refptr &operator =(const refptr o) + const refptr &operator =(const refptr &o) { *this = o.p; return *this; } T &operator * () const { return *p; } - T *operator ->() const { return p; } + T *operator ->() const { return p; } operator T *() const { return p; } }; @@ -460,10 +511,15 @@ : this->end (); } + void push_back (T *obj) + { + std::vector >::push_back (obj); + obj->*indexmember = this->size (); + } + void insert (T *obj) { push_back (obj); - obj->*indexmember = this->size (); } void insert (T &obj) @@ -503,13 +559,13 @@ typedef double tstamp; -// return current time as timestampe +// return current time as timestamp tstamp now (); int similar_direction (int a, int b); -// like printf, but returns a std::string -const std::string format (const char *format, ...); +// like sprintf, but returns a "static" buffer +const char *format (const char *format, ...); #endif