Geschrieben von: / Posted by: Lance Perkins at 06 March 2004 02:32:55:
I discovered that in SMP mode, there is a serious bug at the end of the function IterateInt, in search.c.
The code:
if(!sd->master) {
FreePosition(sd->position);
FreeSearchData(sd);
}
sd->best_move = mvs[0];
accesses memory (sd) that has already been freed!!!
This should be:
if(!sd->master) {
FreePosition(sd->position);
FreeSearchData(sd);
}
else {
sd->best_move = mvs[0];
}
The best_move property is only ever used by the main/master (non-helper) thread.
Below are the steps to compile Amy 0.8.7, for either SMP or non-SMP mode, using MSVC or GCC/MinGW. You don't need pthread libs for this (who needs pthreads in Win32? we got rid of Cygwin dll with MinGW did we not?).
After you make these changes, the code should still build correctly in Unix/Linux.
untar/unzip
cd src
copy ..\config.h.in config.h
Notepad config.h
Add:
#define VERSION "0.8.7"
Replace:
#undef MP
with:
// #undef MP
Replace:
#undef HAVE_LIBPTHREAD
with:
#if MP
#define HAVE_LIBPTHREAD
#endif
Notepad amy.h
Replace:
#if HAVE_LIBPTHREAD
#include "pthread.h"
#endif
With:
#if HAVE_LIBPTHREAD
#if _WIN32
#define pthread_mutex_lock(m_) WaitForSingleObject(*(m_),INFINITE)
#define pthread_mutex_unlock(m_) ReleaseMutex(*(m_))
#define pthread_mutex_t HANDLE
#define PTHREAD_MUTEX_INITIALIZER ((HANDLE)NULL)
#define pthread_t HANDLE
#define pthread_join(t_,x_) WaitForSingleObject(t_,INFINITE)
#define pthread_create(tp_,a_,fp_,p_) (*(tp_) = CreateThread (NULL,1024*1024,fp_,p_,0,NULL))
#define pthread_attr_t int
#define pthread_attr_init(a_)
#define pthread_attr_setscope(a_,n_)
#define PTHREAD_SCOPE_SYSTEM 0
#else
#include "pthread.h"
#endif
#endif
Add:
typedef unsigned __int64 hash_t;
in the same place as:
typedef unsigned __int64 ran_t;
Notepad hashtable.c
At the end of the AllocateHT function, add:
#if MP && _WIN_32
TranspositionMutex = CreateMutex (NULL, FALSE, NULL);
PawnMutex = CreateMutex (NULL, FALSE, NULL);
ScoreMutex = CreateMutex (NULL, FALSE, NULL);
#endif
Notepad probe.c
At the end of the InitEGTB function, add:
#if MP && _WIN_32
EGTBMutex = CreateMutex (NULL, FALSE, NULL);
#endif
Notepad random.c
Replace:
double result = (double) Random64();
with:
#if _WIN32
double result = (double) (__int64) Random64();
#else
double result = (double) Random64();
#endif
Notepad search.c
Replace:
static void *IterateInt(void *x)
with:
#if _WIN32
static DWORD WINAPI IterateInt(LPVOID x)
#else
static void *IterateInt(void *x)
#endif
In function IterateInt, replace:
if(!sd->master) {
FreePosition(sd->position);
FreeSearchData(sd);
}
sd->best_move = mvs[0];
with:
if(!sd->master) {
FreePosition(sd->position);
FreeSearchData(sd);
}
else {
sd->best_move = mvs[0];
}
In function IterateInt, replace:
return NULL;
with:
#if _WIN32
return 0;
#else
return NULL;
#endif
Notepad tbindex.c
Replace:
extern "C" int TB_FASTCALL L_TbtProbeTable
with:
extern "C" int L_TbtProbeTable
Using MSVC (remove "-DMP=1" if you don't want SMP):
del *.obj
cl -nologo -DMP=1 -I. -c bitboard.c bookup.c commands.c dbase.c eco.c hashtable.c
cl -nologo -DMP=1 -I. -c init.c learn.c main.c mates.c movedata.c next.c pgn.c
cl -nologo -DMP=1 -I. -c probe.c random.c recog.c score.c search.c search_io.c
cl -nologo -DMP=1 -I. -c state_machine.c swap.c time_ctl.c utils.c version.c
cl -nologo -DMP=1 -c mytb.cpp
cl -Feamy.exe *.obj
Using GCC/MinGW32 (remove "-DMP=1" if you don't want SMP):
del *.o
gcc -O3 -DMP=1 -I. -c bitboard.c bookup.c commands.c dbase.c eco.c hashtable.c
gcc -O3 -DMP=1 -I. -c init.c learn.c main.c mates.c movedata.c next.c pgn.c
gcc -O3 -DMP=1 -I. -c probe.c random.c recog.c score.c search.c search_io.c
gcc -O3 -DMP=1 -I. -c state_machine.c swap.c time_ctl.c utils.c version.c
gcc -O3 -DMP=1 -I. -c mytb.cpp
gcc -o amy.exe *.o