diff options
Diffstat (limited to 'src/common')
-rw-r--r-- | src/common/Makefile | 3 | ||||
-rw-r--r-- | src/common/core.c | 10 | ||||
-rw-r--r-- | src/common/lock.c | 11 | ||||
-rw-r--r-- | src/common/mt_rand.c | 110 | ||||
-rw-r--r-- | src/common/mt_rand.h | 8 | ||||
-rw-r--r-- | src/common/utils.h | 6 |
6 files changed, 138 insertions, 10 deletions
diff --git a/src/common/Makefile b/src/common/Makefile index b5b8f7c..9218a55 100644 --- a/src/common/Makefile +++ b/src/common/Makefile @@ -1,4 +1,4 @@ -txt sql all: core.o socket.o timer.o grfio.o db.o lock.o nullpo.o malloc.o +txt sql all: core.o socket.o timer.o grfio.o db.o lock.o nullpo.o malloc.o mt_rand.o core.o: core.c core.h socket.o: socket.c socket.h mmo.h @@ -8,6 +8,7 @@ db.o: db.c db.h lock.o: lock.h nullpo.o: nullpo.c nullpo.h malloc.o: malloc.c malloc.h +mt_rand.o: mt_rand.c mt_rand.h clean: rm -f *.o diff --git a/src/common/core.c b/src/common/core.c index 2546f4e..94a754b 100644 --- a/src/common/core.c +++ b/src/common/core.c @@ -7,11 +7,13 @@ #include <unistd.h> #endif #include <signal.h> +#include <wait.h> #include "core.h" #include "socket.h" #include "timer.h" #include "version.h" +#include "mt_rand.h" #ifdef MEMWATCH #include "memwatch.h" @@ -48,6 +50,9 @@ static void sig_proc(int sn) } exit(0); break; + case SIGCHLD: + wait(&i); + break; } } @@ -129,13 +134,16 @@ int main(int argc,char **argv) { int next; + mt_seed(time(NULL) ^ getpid() ^ getppid()); + Net_Init(); do_socket(); compat_signal(SIGPIPE,SIG_IGN); compat_signal(SIGTERM,sig_proc); compat_signal(SIGINT,sig_proc); - + compat_signal(SIGCHLD,sig_proc); + // Signal to create coredumps by system when necessary (crash) compat_signal(SIGSEGV, SIG_DFL); #ifndef LCCWIN32 diff --git a/src/common/lock.c b/src/common/lock.c index 67001f9..42bbff0 100644 --- a/src/common/lock.c +++ b/src/common/lock.c @@ -1,4 +1,5 @@ +#include <unistd.h> #include <stdio.h> #include "lock.h" #include "socket.h" @@ -10,13 +11,13 @@ FILE* lock_fopen(const char* filename,int *info) { char newfile[512]; FILE *fp; - int no = 0; + int no = getpid(); // 安全なファイル名を得る(手抜き) do { - sprintf(newfile,"%s_%04d.tmp",filename,++no); - } while((fp = fopen_(newfile,"r")) && (fclose_(fp), no<9999) ); - *info = no; + sprintf(newfile,"%s_%d.tmp",filename,no++); + } while((fp = fopen_(newfile,"r")) && fclose_(fp)); + *info = --no; return fopen_(newfile,"w"); } @@ -26,7 +27,7 @@ int lock_fclose(FILE *fp,const char* filename,int *info) { char newfile[512]; if(fp != NULL) { ret = fclose_(fp); - sprintf(newfile,"%s_%04d.tmp",filename,*info); + sprintf(newfile,"%s_%d.tmp",filename,*info); remove(filename); // このタイミングで落ちると最悪。 rename(newfile,filename); diff --git a/src/common/mt_rand.c b/src/common/mt_rand.c new file mode 100644 index 0000000..ab733ae --- /dev/null +++ b/src/common/mt_rand.c @@ -0,0 +1,110 @@ +/* +// This is the ``Mersenne Twister'' random number generator MT19937, which +// generates pseudorandom integers uniformly distributed in 0..(2^32 - 1) +// starting from any odd seed in 0..(2^32 - 1). This version is a recode +// by Shawn Cokus (Cokus@math.washington.edu) on March 8, 1998 of a version by +// Takuji Nishimura (who had suggestions from Topher Cooper and Marc Rieffel in +// July-August 1997). +// +// Effectiveness of the recoding (on Goedel2.math.washington.edu, a DEC Alpha +// running OSF/1) using GCC -O3 as a compiler: before recoding: 51.6 sec. to +// generate 300 million random numbers; after recoding: 24.0 sec. for the same +// (i.e., 46.5% of original time), so speed is now about 12.5 million random +// number generations per second on this machine. +// +// According to the URL <http://www.math.keio.ac.jp/~matumoto/emt.html> +// (and paraphrasing a bit in places), the Mersenne Twister is ``designed +// with consideration of the flaws of various existing generators,'' has +// a period of 2^19937 - 1, gives a sequence that is 623-dimensionally +// equidistributed, and ``has passed many stringent tests, including the +// die-hard test of G. Marsaglia and the load test of P. Hellekalek and +// S. Wegenkittl.'' It is efficient in memory usage (typically using 2506 +// to 5012 bytes of static data, depending on data type sizes, and the code +// is quite short as well). It generates random numbers in batches of 624 +// at a time, so the caching and pipelining of modern systems is exploited. +// It is also divide- and mod-free. +// +// This library is free software; you can redistribute it and/or modify it +// under the terms of the GNU Library General Public License as published by +// the Free Software Foundation (either version 2 of the License or, at your +// option, any later version). This library 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 Library General Public License for more details. You should have +// received a copy of the GNU Library General Public License along with this +// library; if not, write to the Free Software Foundation, Inc., 59 Temple +// Place, Suite 330, Boston, MA 02111-1307, USA. +// +// The code as Shawn received it included the following notice: +// +// Copyright (C) 1997 Makoto Matsumoto and Takuji Nishimura. When +// you use this, send an e-mail to <matumoto@math.keio.ac.jp> with +// an appropriate reference to your work. +// +// It would be nice to CC: <Cokus@math.washington.edu> when you write. +// +*/ + +#include <time.h> +#include "mt_rand.h" + +#define N (624) /* length of state vector */ +#define M (397) /* a period parameter */ +#define K (0x9908B0DFU) /* a magic constant */ +#define hiBit(u) ((u) & 0x80000000U) /* mask all but highest bit of u */ +#define loBit(u) ((u) & 0x00000001U) /* mask all but lowest bit of u */ +#define loBits(u) ((u) & 0x7FFFFFFFU) /* mask the highest bit of u */ +#define mixBits(u, v) (hiBit(u)|loBits(v)) /* move hi bit of u to hi bit of v */ + +static unsigned long state[N+1]; /* state vector + 1 extra to not violate ANSI C */ +static unsigned long *next; /* next random value is computed from here */ +static int left = -1; /* can *next++ this many times before reloading */ + + +void mt_seed(unsigned long seed) +{ + register unsigned long x = (seed | 1U) & 0xFFFFFFFFU, *s = state; + register int j; + + for(left=0, *s++=x, j=N; --j; + *s++ = (x*=69069U) & 0xFFFFFFFFU); +} + + +unsigned long mt_reload(void) +{ + register unsigned long *p0=state, *p2=state+2, *pM=state+M, s0, s1; + register int j; + + if(left < -1) + mt_seed(time(NULL)); + + left=N-1, next=state+1; + + for(s0=state[0], s1=state[1], j=N-M+1; --j; s0=s1, s1=*p2++) + *p0++ = *pM++ ^ (mixBits(s0, s1) >> 1) ^ (loBit(s1) ? K : 0U); + + for(pM=state, j=M; --j; s0=s1, s1=*p2++) + *p0++ = *pM++ ^ (mixBits(s0, s1) >> 1) ^ (loBit(s1) ? K : 0U); + + s1=state[0], *p0 = *pM ^ (mixBits(s0, s1) >> 1) ^ (loBit(s1) ? K : 0U); + s1 ^= (s1 >> 11); + s1 ^= (s1 << 7) & 0x9D2C5680U; + s1 ^= (s1 << 15) & 0xEFC60000U; + return(s1 ^ (s1 >> 18)); +} + + +unsigned long mt_random(void) +{ + unsigned long y; + + if(--left < 0) + return(mt_reload()); + + y = *next++; + y ^= (y >> 11); + y ^= (y << 7) & 0x9D2C5680U; + y ^= (y << 15) & 0xEFC60000U; + return(y ^ (y >> 18)); +} diff --git a/src/common/mt_rand.h b/src/common/mt_rand.h new file mode 100644 index 0000000..07f6ef0 --- /dev/null +++ b/src/common/mt_rand.h @@ -0,0 +1,8 @@ +#ifndef __mt_rand_h +#define __mt_rand_h + +void mt_seed(unsigned long seed); +unsigned long mt_reload(void); +unsigned long mt_random(void); + +#endif /* __mt_rand_h */ diff --git a/src/common/utils.h b/src/common/utils.h index 794a0b6..0b006c3 100644 --- a/src/common/utils.h +++ b/src/common/utils.h @@ -1,3 +1,4 @@ +#include "mt_rand.h" #ifndef NULL #define NULL (void *)0 @@ -33,10 +34,9 @@ /* * ModuloRand and ModuloPlusRand. These macros are used to replace the - * vast number of calls to rand()%mod which is low-order bits. These - * instead use the high-order bits as suggested in the man page of rand(). + * vast number of calls to rand()%mod .. * MRAND(10), returns 0-9. * MPRAND(5,10) returns 5-14. */ -#define MRAND(mod) (int) ((float)mod * (rand() / (RAND_MAX + 1.0))) +#define MRAND(mod) (int) (mt_random() % mod) #define MPRAND(add, mod) add + MRAND(mod) |