ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/common/utils.C
Revision: 1.94
Committed: Wed Nov 11 03:52:44 2009 UTC (14 years, 6 months ago) by root
Content type: text/plain
Branch: MAIN
CVS Tags: rel-2_92, rel-2_93
Changes since 1.93: +17 -0 lines
Log Message:
fix icecube thawing bug

File Contents

# User Rev Content
1 elmex 1.1 /*
2 root 1.68 * This file is part of Deliantra, the Roguelike Realtime MMORPG.
3 pippijn 1.39 *
4 root 1.93 * Copyright (©) 2005,2006,2007,2008,2009 Marc Alexander Lehmann / Robin Redeker / the Deliantra team
5 pippijn 1.39 *
6 root 1.89 * Deliantra is free software: you can redistribute it and/or modify it under
7     * the terms of the Affero GNU General Public License as published by the
8     * Free Software Foundation, either version 3 of the License, or (at your
9     * option) any later version.
10 pippijn 1.39 *
11 root 1.60 * This program is distributed in the hope that it will be useful,
12     * but WITHOUT ANY WARRANTY; without even the implied warranty of
13     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14     * GNU General Public License for more details.
15 pippijn 1.39 *
16 root 1.89 * You should have received a copy of the Affero GNU General Public License
17     * and the GNU General Public License along with this program. If not, see
18     * <http://www.gnu.org/licenses/>.
19 root 1.57 *
20 root 1.68 * The authors can be reached via e-mail to <support@deliantra.net>
21 pippijn 1.39 */
22 elmex 1.1
23     /*
24 root 1.92 * General convenience functions for deliantra.
25 elmex 1.1 */
26    
27 root 1.37 #include <cstdlib>
28     #include <sys/types.h>
29     #include <unistd.h>
30     #include <sys/time.h>
31     #include <time.h>
32     #include <signal.h>
33    
34 elmex 1.1 #include <global.h>
35     #include <material.h>
36 sf-marcmagus 1.87 #include <object.h>
37 elmex 1.1
38 root 1.79 #include <sys/time.h>
39     #include <sys/resource.h>
40    
41 root 1.4 #include <glib.h>
42    
43 root 1.63 refcnt_base::refcnt_t refcnt_dummy;
44 root 1.74 ssize_t slice_alloc;
45 root 1.77 rand_gen rndm, rmg_rndm;
46 root 1.40
47 root 1.94 #if !GCC_VERSION(3,4)
48     int least_significant_bit (uint32_t x)
49     {
50     x &= -x; // this isolates the lowest bit
51    
52     int r = 0;
53    
54     if (x & 0xaaaaaaaa) r += 1;
55     if (x & 0xcccccccc) r += 2;
56     if (x & 0xf0f0f0f0) r += 4;
57     if (x & 0xff00ff00) r += 8;
58     if (x & 0xffff0000) r += 16;
59    
60     return r;
61     }
62     #endif
63    
64 root 1.42 void
65     tausworthe_random_generator::seed (uint32_t seed)
66 root 1.40 {
67 root 1.74 state [0] = seed * 69069U; if (state [0] < 2U) state [0] += 2U;
68     state [1] = state [0] * 69069U; if (state [0] < 8U) state [0] += 8U;
69     state [2] = state [1] * 69069U; if (state [0] < 16U) state [0] += 16U;
70     state [3] = state [2] * 69069U; if (state [0] < 128U) state [0] += 128U;
71 root 1.40
72     for (int i = 11; --i; )
73 root 1.84 next ();
74 root 1.40 }
75    
76     uint32_t
77     tausworthe_random_generator::next ()
78     {
79     state [0] = ((state [0] & 0xFFFFFFFEU) << 18U) ^ (((state [0] << 6U) ^ state [0]) >> 13U);
80     state [1] = ((state [1] & 0xFFFFFFF8U) << 2U) ^ (((state [1] << 2U) ^ state [1]) >> 27U);
81     state [2] = ((state [2] & 0xFFFFFFF0U) << 7U) ^ (((state [2] << 13U) ^ state [2]) >> 21U);
82     state [3] = ((state [3] & 0xFFFFFF80U) << 13U) ^ (((state [3] << 3U) ^ state [3]) >> 12U);
83    
84     return state [0] ^ state [1] ^ state [2] ^ state [3];
85     }
86    
87 root 1.84 template<class generator>
88 root 1.42 uint32_t
89 root 1.84 random_number_generator<generator>::get_range (uint32_t num)
90 root 1.42 {
91 root 1.84 return (this->next () * (uint64_t)num) >> 32U;
92 root 1.42 }
93    
94     // return a number within (min .. max)
95 root 1.84 template<class generator>
96 root 1.42 int
97 root 1.84 random_number_generator<generator>::get_range (int r_min, int r_max)
98 root 1.42 {
99 root 1.50 return r_min + get_range (max (r_max - r_min + 1, 0));
100 root 1.42 }
101    
102 root 1.84 template struct random_number_generator<tausworthe_random_generator>;
103     template struct random_number_generator<xorshift_random_generator>;
104    
105 sf-marcmagus 1.87 /******************************************************************************/
106    
107     /* Checks a player-provided string which will become the msg property of
108     * an object for dangerous input.
109     */
110     bool
111     msg_is_safe (const char *msg)
112     {
113     bool safe = true;
114    
115     /* Trying to cheat by getting data into the object */
116 root 1.88 if (!strncmp (msg, "endmsg", sizeof ("endmsg") - 1)
117     || strstr (msg, "\nendmsg"))
118 sf-marcmagus 1.87 safe = false;
119    
120     /* Trying to make the object talk, and potentially access arbitrary code */
121     if (object::msg_has_dialogue (msg))
122     safe = false;
123    
124     return safe;
125     }
126    
127 root 1.14 /////////////////////////////////////////////////////////////////////////////
128    
129 root 1.37 void
130     fork_abort (const char *msg)
131     {
132     if (!fork ())
133     {
134 root 1.80 signal (SIGINT , SIG_IGN);
135     signal (SIGTERM, SIG_IGN);
136     signal (SIGABRT, SIG_IGN);
137 root 1.79
138 root 1.81 signal (SIGSEGV, SIG_DFL);
139     signal (SIGBUS , SIG_DFL);
140     signal (SIGILL , SIG_DFL);
141     signal (SIGTRAP, SIG_DFL);
142    
143 root 1.52 // try to put corefiles into a subdirectory, if existing, to allow
144     // an administrator to reduce the I/O load.
145     chdir ("cores");
146 root 1.79
147     // try to detach us from as many external dependencies as possible
148     // as coredumping can take time by closing all fd's.
149     {
150     struct rlimit lim;
151    
152     if (getrlimit (RLIMIT_NOFILE, &lim))
153     lim.rlim_cur = 1024;
154    
155     for (int i = 0; i < lim.rlim_cur; ++i)
156     close (i);
157     }
158    
159 root 1.81 {
160     sigset_t empty;
161     sigemptyset (&empty);
162     sigprocmask (SIG_SETMASK, &empty, 0);
163     }
164    
165     // try to coredump with SIGTRAP
166     kill (getpid (), SIGTRAP);
167 root 1.37 abort ();
168     }
169    
170 root 1.38 LOG (llevError, "fork abort: %s\n", msg);
171 root 1.37 }
172 root 1.38
173 root 1.25 void *salloc_ (int n) throw (std::bad_alloc)
174 root 1.10 {
175 root 1.25 void *ptr = g_slice_alloc (n);
176 root 1.13
177 root 1.23 if (!ptr)
178 root 1.13 throw std::bad_alloc ();
179 root 1.4
180 root 1.74 slice_alloc += n;
181 root 1.23 return ptr;
182     }
183    
184 root 1.25 void *salloc_ (int n, void *src) throw (std::bad_alloc)
185 root 1.23 {
186 root 1.25 void *ptr = salloc_ (n);
187 root 1.23
188 root 1.24 if (src)
189 root 1.25 memcpy (ptr, src, n);
190 root 1.24 else
191 root 1.25 memset (ptr, 0, n);
192 root 1.23
193     return ptr;
194 root 1.3 }
195 root 1.11
196 root 1.69 /******************************************************************************/
197    
198 root 1.72 #if DEBUG_SALLOC
199 root 1.69
200 root 1.70 #define MAGIC 0xa1b2c35543deadLL
201 root 1.69
202     void *g_slice_alloc (unsigned long size)
203     {
204     unsigned long *p = (unsigned long *) (g_slice_alloc)(size + sizeof (unsigned long));
205     *p++ = size ^ MAGIC;
206     //fprintf (stderr, "g_slice_alloc %ld %p\n", size, p);//D
207     return (void *)p;
208     }
209    
210     void *g_slice_alloc0 (unsigned long size)
211     {
212     return memset (g_slice_alloc (size), 0, size);
213     }
214    
215     void g_slice_free1 (unsigned long size, void *ptr)
216     {
217 root 1.74 //fprintf (stderr, "g_slice_free %ld %p\n", size, ptr);//D
218 root 1.69 if (expect_true (ptr))
219     {
220     unsigned long *p = (unsigned long *)ptr;
221     unsigned long s = *--p ^ MAGIC;
222    
223 root 1.71 if (size != (unsigned long)(*p ^ MAGIC))
224 root 1.74 {
225     LOG (logBacktrace | llevError, "slice free size (%lx) doesn't match alloc size (%lx)\n", size, s);
226     abort ();
227     }
228 root 1.69
229     *p = MAGIC;
230    
231     (g_slice_free1)(s + sizeof (unsigned long), p);
232     }
233     }
234    
235     #endif
236    
237     /******************************************************************************/
238    
239 root 1.86 int
240     assign (char *dst, const char *src, int maxsize)
241 root 1.11 {
242     if (!src)
243     src = "";
244    
245     int len = strlen (src);
246    
247 root 1.86 if (len >= maxsize)
248 root 1.11 {
249 root 1.86 if (maxsize <= 4)
250 root 1.11 {
251 root 1.86 memset (dst, '.', maxsize - 2);
252     dst [maxsize - 1] = 0;
253 root 1.11 }
254     else
255     {
256 root 1.86 memcpy (dst, src, maxsize - 4);
257     memcpy (dst + maxsize - 4, "...", 4);
258 root 1.11 }
259 root 1.86
260     len = maxsize;
261 root 1.11 }
262     else
263 root 1.86 memcpy (dst, src, ++len);
264    
265     return len;
266 root 1.11 }
267    
268 root 1.90 char *
269     vformat (const char *format, va_list ap)
270     {
271     static dynbuf_text buf; buf.clear ();
272     buf.vprintf (format, ap);
273     return buf;
274     }
275    
276     char *
277 root 1.51 format (const char *format, ...)
278     {
279 root 1.65 va_list ap;
280     va_start (ap, format);
281 root 1.90 char *buf = vformat (format, ap);
282 root 1.65 va_end (ap);
283    
284     return buf;
285 root 1.51 }
286    
287 root 1.23 tstamp now ()
288     {
289     struct timeval tv;
290    
291     gettimeofday (&tv, 0);
292     return tstamp (tv.tv_sec) + tstamp (tv.tv_usec) * tstamp (1e-6);
293     }
294 root 1.17
295 root 1.32 int
296     similar_direction (int a, int b)
297     {
298     if (!a || !b)
299     return 0;
300    
301     int diff = (b - a) & 7;
302     return diff <= 1 || diff >= 7;
303     }
304    
305 root 1.48 /* crc32 0xdebb20e3 table and supplementary functions. */
306     extern const uint32_t crc_32_tab[256] =
307     {
308     0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL,
309     0x706af48fUL, 0xe963a535UL, 0x9e6495a3UL, 0x0edb8832UL, 0x79dcb8a4UL,
310     0xe0d5e91eUL, 0x97d2d988UL, 0x09b64c2bUL, 0x7eb17cbdUL, 0xe7b82d07UL,
311     0x90bf1d91UL, 0x1db71064UL, 0x6ab020f2UL, 0xf3b97148UL, 0x84be41deUL,
312     0x1adad47dUL, 0x6ddde4ebUL, 0xf4d4b551UL, 0x83d385c7UL, 0x136c9856UL,
313     0x646ba8c0UL, 0xfd62f97aUL, 0x8a65c9ecUL, 0x14015c4fUL, 0x63066cd9UL,
314     0xfa0f3d63UL, 0x8d080df5UL, 0x3b6e20c8UL, 0x4c69105eUL, 0xd56041e4UL,
315     0xa2677172UL, 0x3c03e4d1UL, 0x4b04d447UL, 0xd20d85fdUL, 0xa50ab56bUL,
316     0x35b5a8faUL, 0x42b2986cUL, 0xdbbbc9d6UL, 0xacbcf940UL, 0x32d86ce3UL,
317     0x45df5c75UL, 0xdcd60dcfUL, 0xabd13d59UL, 0x26d930acUL, 0x51de003aUL,
318     0xc8d75180UL, 0xbfd06116UL, 0x21b4f4b5UL, 0x56b3c423UL, 0xcfba9599UL,
319     0xb8bda50fUL, 0x2802b89eUL, 0x5f058808UL, 0xc60cd9b2UL, 0xb10be924UL,
320     0x2f6f7c87UL, 0x58684c11UL, 0xc1611dabUL, 0xb6662d3dUL, 0x76dc4190UL,
321     0x01db7106UL, 0x98d220bcUL, 0xefd5102aUL, 0x71b18589UL, 0x06b6b51fUL,
322     0x9fbfe4a5UL, 0xe8b8d433UL, 0x7807c9a2UL, 0x0f00f934UL, 0x9609a88eUL,
323     0xe10e9818UL, 0x7f6a0dbbUL, 0x086d3d2dUL, 0x91646c97UL, 0xe6635c01UL,
324     0x6b6b51f4UL, 0x1c6c6162UL, 0x856530d8UL, 0xf262004eUL, 0x6c0695edUL,
325     0x1b01a57bUL, 0x8208f4c1UL, 0xf50fc457UL, 0x65b0d9c6UL, 0x12b7e950UL,
326     0x8bbeb8eaUL, 0xfcb9887cUL, 0x62dd1ddfUL, 0x15da2d49UL, 0x8cd37cf3UL,
327     0xfbd44c65UL, 0x4db26158UL, 0x3ab551ceUL, 0xa3bc0074UL, 0xd4bb30e2UL,
328     0x4adfa541UL, 0x3dd895d7UL, 0xa4d1c46dUL, 0xd3d6f4fbUL, 0x4369e96aUL,
329     0x346ed9fcUL, 0xad678846UL, 0xda60b8d0UL, 0x44042d73UL, 0x33031de5UL,
330     0xaa0a4c5fUL, 0xdd0d7cc9UL, 0x5005713cUL, 0x270241aaUL, 0xbe0b1010UL,
331     0xc90c2086UL, 0x5768b525UL, 0x206f85b3UL, 0xb966d409UL, 0xce61e49fUL,
332     0x5edef90eUL, 0x29d9c998UL, 0xb0d09822UL, 0xc7d7a8b4UL, 0x59b33d17UL,
333     0x2eb40d81UL, 0xb7bd5c3bUL, 0xc0ba6cadUL, 0xedb88320UL, 0x9abfb3b6UL,
334     0x03b6e20cUL, 0x74b1d29aUL, 0xead54739UL, 0x9dd277afUL, 0x04db2615UL,
335     0x73dc1683UL, 0xe3630b12UL, 0x94643b84UL, 0x0d6d6a3eUL, 0x7a6a5aa8UL,
336     0xe40ecf0bUL, 0x9309ff9dUL, 0x0a00ae27UL, 0x7d079eb1UL, 0xf00f9344UL,
337     0x8708a3d2UL, 0x1e01f268UL, 0x6906c2feUL, 0xf762575dUL, 0x806567cbUL,
338     0x196c3671UL, 0x6e6b06e7UL, 0xfed41b76UL, 0x89d32be0UL, 0x10da7a5aUL,
339     0x67dd4accUL, 0xf9b9df6fUL, 0x8ebeeff9UL, 0x17b7be43UL, 0x60b08ed5UL,
340     0xd6d6a3e8UL, 0xa1d1937eUL, 0x38d8c2c4UL, 0x4fdff252UL, 0xd1bb67f1UL,
341     0xa6bc5767UL, 0x3fb506ddUL, 0x48b2364bUL, 0xd80d2bdaUL, 0xaf0a1b4cUL,
342     0x36034af6UL, 0x41047a60UL, 0xdf60efc3UL, 0xa867df55UL, 0x316e8eefUL,
343     0x4669be79UL, 0xcb61b38cUL, 0xbc66831aUL, 0x256fd2a0UL, 0x5268e236UL,
344     0xcc0c7795UL, 0xbb0b4703UL, 0x220216b9UL, 0x5505262fUL, 0xc5ba3bbeUL,
345     0xb2bd0b28UL, 0x2bb45a92UL, 0x5cb36a04UL, 0xc2d7ffa7UL, 0xb5d0cf31UL,
346     0x2cd99e8bUL, 0x5bdeae1dUL, 0x9b64c2b0UL, 0xec63f226UL, 0x756aa39cUL,
347     0x026d930aUL, 0x9c0906a9UL, 0xeb0e363fUL, 0x72076785UL, 0x05005713UL,
348     0x95bf4a82UL, 0xe2b87a14UL, 0x7bb12baeUL, 0x0cb61b38UL, 0x92d28e9bUL,
349     0xe5d5be0dUL, 0x7cdcefb7UL, 0x0bdbdf21UL, 0x86d3d2d4UL, 0xf1d4e242UL,
350     0x68ddb3f8UL, 0x1fda836eUL, 0x81be16cdUL, 0xf6b9265bUL, 0x6fb077e1UL,
351     0x18b74777UL, 0x88085ae6UL, 0xff0f6a70UL, 0x66063bcaUL, 0x11010b5cUL,
352     0x8f659effUL, 0xf862ae69UL, 0x616bffd3UL, 0x166ccf45UL, 0xa00ae278UL,
353     0xd70dd2eeUL, 0x4e048354UL, 0x3903b3c2UL, 0xa7672661UL, 0xd06016f7UL,
354     0x4969474dUL, 0x3e6e77dbUL, 0xaed16a4aUL, 0xd9d65adcUL, 0x40df0b66UL,
355     0x37d83bf0UL, 0xa9bcae53UL, 0xdebb9ec5UL, 0x47b2cf7fUL, 0x30b5ffe9UL,
356     0xbdbdf21cUL, 0xcabac28aUL, 0x53b39330UL, 0x24b4a3a6UL, 0xbad03605UL,
357     0xcdd70693UL, 0x54de5729UL, 0x23d967bfUL, 0xb3667a2eUL, 0xc4614ab8UL,
358     0x5d681b02UL, 0x2a6f2b94UL, 0xb40bbe37UL, 0xc30c8ea1UL, 0x5a05df1bUL,
359     0x2d02ef8dL
360     };
361    
362 root 1.73 void thread::start (void *(*start_routine)(void *), void *arg)
363     {
364 root 1.75 pthread_attr_t attr;
365    
366     pthread_attr_init (&attr);
367     pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);
368     pthread_attr_setstacksize (&attr, PTHREAD_STACK_MIN < sizeof (long) * 4096
369     ? sizeof (long) * 4096 : PTHREAD_STACK_MIN);
370     #ifdef PTHREAD_SCOPE_PROCESS
371     pthread_attr_setscope (&attr, PTHREAD_SCOPE_PROCESS);
372     #endif
373    
374 root 1.73 sigset_t fullsigset, oldsigset;
375     sigfillset (&fullsigset);
376    
377     pthread_sigmask (SIG_SETMASK, &fullsigset, &oldsigset);
378    
379 root 1.75 if (pthread_create (&id, &attr, start_routine, arg))
380 root 1.73 cleanup ("unable to create a new thread");
381    
382     pthread_sigmask (SIG_SETMASK, &oldsigset, 0);
383     }
384 root 1.75