Skip to content

Commit

Permalink
Initial win32 port using cross compilation from Mac [win32]
Browse files Browse the repository at this point in the history
  • Loading branch information
kervinck committed Oct 7, 2015
1 parent 93cc42a commit 90b92b7
Show file tree
Hide file tree
Showing 9 changed files with 275 additions and 58 deletions.
22 changes: 18 additions & 4 deletions Makefile
@@ -1,15 +1,29 @@
CFLAGS=-std=c11 -pedantic -Wall -O3 -DfloydVersion=0.1a
floydVersion:=0.1a

CFLAGS:=-std=c11 -pedantic -Wall -O3 -DfloydVersion=$(floydVersion)

# Cross-compiler for windows
# Installed from gcc-4.8.0-qt-4.8.4-for-mingw32.dmg
xcc_win32:=/usr/local/gcc-4.8.0-qt-4.8.4-for-mingw32/win32-gcc/bin/i586-mingw32-gcc

all: module floyd
win: $(win32_exe)

win32_exe:=floyd$(floydVersion).w32.exe
win: $(win32_exe)

# As Python module
module:
python setup.py build

# As UCI engine
# As native UCI engine
SOURCES=cplus.c evaluate.c floydmain.c format.c kpk.c moves.c parse.c search.c ttable.c uci.c zobrist.c
floyd: $(addprefix Source/, $(SOURCES)) $(wildcard Source/*.h)
gcc $(CFLAGS) -o $@ $(addprefix Source/, $(SOURCES))
$(CC) $(CFLAGS) -o $@ $(addprefix Source/, $(SOURCES))

# As Win32 UCI engine
$(win32_exe): $(addprefix Source/, $(SOURCES)) $(wildcard Source/*.h)
$(xcc_win32) $(CFLAGS) -o $@ $(addprefix Source/, $(SOURCES))

# TODO: allow testing before install
test: install
Expand Down Expand Up @@ -52,6 +66,6 @@ install:

clean:
python setup.py clean --all
rm -f floyd
rm -f floyd $(win32_exe)

# vi: noexpandtab
157 changes: 155 additions & 2 deletions Source/cplus.c
Expand Up @@ -39,12 +39,26 @@
+----------------------------------------------------------------------*/

#include <errno.h>
#include <math.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <time.h>

#include "cplus.h"

#if defined(_WIN32)
#include <windows.h>
#include <process.h>
#include <sys/timeb.h>
#endif

#if defined(POSIX)
#include <pthread.h>
#include <unistd.h>
#endif

/*----------------------------------------------------------------------+
| Exceptions |
+----------------------------------------------------------------------*/
Expand Down Expand Up @@ -141,10 +155,17 @@ err_t list_ensure_len(void **v, int *maxLen, int minLen, int unit, int newLen)
+----------------------------------------------------------------------*/

/*
* Get CPU clock in seconds
* Get clock in seconds
*/
double xclock(void)
{
#if defined(WIN32)
struct _timeb t;
_ftime(&t);
return t.time + t.millitm * 1e-3;
#endif
#if defined(POSIX)
// TODO: why are we using the CPU time and not wall time...
struct rusage ru;

int r = getrusage(RUSAGE_SELF, &ru);
Expand All @@ -156,6 +177,7 @@ double xclock(void)
(ru.ru_utime.tv_sec + ru.ru_stime.tv_sec);

return clock;
#endif
}

/*----------------------------------------------------------------------+
Expand All @@ -175,8 +197,9 @@ char *stringCopy(char *s, const char *t)
| readline |
+----------------------------------------------------------------------*/

int readLine(void *fp, char **pLine, int *pSize)
int readLine(void *fpPointer, char **pLine, int *pSize)
{
FILE *fp = fpPointer;
char *line = *pLine;
int size = *pSize;
int len = 0;
Expand Down Expand Up @@ -226,3 +249,133 @@ int readLine(void *fp, char **pLine, int *pSize)
| |
+----------------------------------------------------------------------*/

#if defined(_WIN32)

static unsigned int __stdcall alarmThreadEntry(void *argsPointer)
{
struct alarm *args = argsPointer;
DWORD millis = ceil(args->alarmTime * 1e3);
Sleep(millis);
args->alarmFunction(args->alarmData);
return 0;
}

xthread_t setAlarm(struct alarm *alarm)
{
if (!alarm)
return null;

HANDLE threadHandle = (HANDLE)_beginthreadex(
null,
0,
alarmThreadEntry,
(void*)alarm,
0,
null);
return (xthread_t)threadHandle;
}

void clearAlarm(xthread_t alarm)
{
if (alarm) {
HANDLE threadHandle = (HANDLE)alarm;
TerminateThread(threadHandle, 0);
WaitForSingleObject(threadHandle, INFINITE);
CloseHandle(threadHandle);
}
}

static unsigned int __stdcall threadEntry(void *argsPointer)
{
struct thread *args = argsPointer;
args->threadFunction(args->threadData);
return 0;
}

xthread_t createThread(struct thread *thread)
{
HANDLE threadHandle = (HANDLE)_beginthreadex(
null,
0,
threadEntry,
thread,
0,
null);
return threadHandle;
}

void joinThread(xthread_t thread)
{
HANDLE threadHandle = (HANDLE)thread;

WaitForSingleObject(threadHandle, INFINITE);
CloseHandle(threadHandle);
}

#endif

#if defined(POSIX)

static void *alarmThreadEntry(void *argsPointer)
{
struct alarm *args = argsPointer;
int r = usleep((useconds_t) (args->alarmTime * 1e6));
if (r != 0)
systemFailure("usleep", r);
args->alarmFunction(args->alarmData);
return null;
}

xthread_t setAlarm(struct alarm *alarm)
{
if (!alarm)
return null;

pthread_t threadHandle;
int r = pthread_create(&threadHandle, null, alarmThreadEntry, alarm);
if (r != 0)
systemFailure("pthread_create", r);

return (xthread_t) threadHandle;
}

void clearAlarm(xthread_t alarm)
{
if (alarm) {
pthread_t threadHandle = (pthread_t) alarm;
int r = pthread_join(threadHandle, null);
if (r != 0)
systemFailure("pthread_join", r);
}
}

static void *threadEntry(void *argsPointer)
{
struct thread *args = argsPointer;
args->threadFunction(args->threadData);
return null;
}

xthread_t createThread(struct thread *thread)
{
pthread_t threadHandle;
int r = pthread_create(&threadHandle, null, threadEntry, thread);
if (r != 0)
systemFailure("pthread_create", r);
return (xthread_t) threadHandle;
}

void joinThread(xthread_t thread)
{
pthread_t threadHandle = (pthread_t) thread;
int r = pthread_join(threadHandle, null);
if (r != 0)
systemFailure("pthread_join", r);
}

#endif

/*----------------------------------------------------------------------+
| |
+----------------------------------------------------------------------*/

37 changes: 37 additions & 0 deletions Source/cplus.h
Expand Up @@ -196,6 +196,43 @@ int xExitMain(err_t err);
void xAbort(err_t err);
void systemFailure(const char *function, int r);

/*----------------------------------------------------------------------+
| Threads and alarms |
+----------------------------------------------------------------------*/

// Definitions

typedef void thread_fn(void *alarmData);

struct alarm {
double alarmTime;
thread_fn *alarmFunction;
void *alarmData;
};

struct thread {
thread_fn *threadFunction;
void *threadData;
};

typedef struct thread_handle *xthread_t;

// Functions

xthread_t setAlarm(struct alarm *alarm);
void clearAlarm(xthread_t alarm);

xthread_t createThread(struct thread *thread);
void joinThread(xthread_t thread);

/*----------------------------------------------------------------------+
| Platform checks |
+----------------------------------------------------------------------*/

#if defined(__unix__) || defined(__APPLE__)
#define POSIX
#endif

/*----------------------------------------------------------------------+
| |
+----------------------------------------------------------------------*/
Expand Down
13 changes: 9 additions & 4 deletions Source/evaluate.c
Expand Up @@ -42,6 +42,7 @@
#include <assert.h>
#define _XOPEN_SOURCE
#include <math.h>

#include <setjmp.h>
#include <stdbool.h>
#include <stdint.h>
Expand All @@ -62,6 +63,10 @@
| Definitions |
+----------------------------------------------------------------------*/

#ifndef M_LN10
#define M_LN10 2.30258509299404568401799145468436421 // log(10)
#endif

#define other(side) ((side) ^ 1)
#define flip(fileOrRank) ((fileOrRank) ^ 7)

Expand Down Expand Up @@ -103,8 +108,8 @@ static double logit(double p);
static int squareOf(Board_t self, int piece);

static int evaluatePawn(const int v[vectorLen],
const int minRank[][2],
const int maxRank[][2],
int minRank[10][2],
int maxRank[10][2],
int fileIndex, int side,
int king, int xking);

Expand Down Expand Up @@ -547,8 +552,8 @@ int evaluate(Board_t self)
+----------------------------------------------------------------------*/

static int evaluatePawn(const int v[vectorLen],
const int maxPawnFromRank1[][2],
const int maxPawnFromRank8[][2],
/*const*/int maxPawnFromRank1[][2], // TODO: why does MinGW complain about const here?
/*const*/int maxPawnFromRank8[][2], // TODO: why does MinGW complain about const here?
int fileIndex,
int side,
int king, int xking)
Expand Down
26 changes: 11 additions & 15 deletions Source/search.c
Expand Up @@ -42,15 +42,11 @@
#include <assert.h>
#include <math.h>
#include <setjmp.h>
#include <signal.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>

// System
#include <unistd.h>

// C extension
#include "cplus.h"

Expand Down Expand Up @@ -79,8 +75,6 @@ static const int pieceValue[] = {

static const int promotionValue[] = { 9, 5, 3, 3 };

static Engine_t globalEngine; // TODO: remove global & all timing decisions & signals from search.c

/*----------------------------------------------------------------------+
| Functions |
+----------------------------------------------------------------------*/
Expand All @@ -100,11 +94,13 @@ static bool repetition(Engine_t self);
| rootSearch |
+----------------------------------------------------------------------*/

static void catchSignal(int signal)
static void stopSearch(void *data)
{
globalEngine->stopFlag = true;
Engine_t self = data;
self->stopFlag = true;
}

// TODO: all timing decisions from search.c
// TODO: aspiration search
void rootSearch(Engine_t self,
int depth,
Expand All @@ -124,10 +120,12 @@ void rootSearch(Engine_t self,
self->tt.now = (self->tt.now + 1) & ones(ttDateBits);
}

// Set alarm
globalEngine = self;
sig_t oldHandler = signal(SIGALRM, catchSignal);
alarm(ceil(alarmTime));
struct alarm alarm = (struct alarm) {
.alarmTime = alarmTime,
.alarmFunction = stopSearch,
.alarmData = self,
};
xthread_t alarmHandle = setAlarm(alarmTime > 0.0 ? &alarm : null);

if (setjmp(self->abortEnv) == 0) { // try search
bool stop = false;
Expand All @@ -149,9 +147,7 @@ void rootSearch(Engine_t self,
(void) infoFunction(infoData);
}

// Clear alarm
signal(SIGALRM, oldHandler);
alarm(0);
clearAlarm(alarmHandle);
}

/*----------------------------------------------------------------------+
Expand Down

0 comments on commit 90b92b7

Please sign in to comment.