00001
00002
00003 #ifndef OSL_DFPNPARALLEL_H
00004 #define OSL_DFPNPARALLEL_H
00005
00006 #include "osl/checkmate/dfpn.h"
00007 #include "osl/misc/lightMutex.h"
00008
00009 namespace osl
00010 {
00011 namespace checkmate
00012 {
00013 struct DfpnShared
00014 {
00015 struct ThreadData
00016 {
00017 HashKey restart_key;
00018 volatile int depth;
00019 volatile bool restart;
00020 LightMutex mutex;
00021 ThreadData() : depth(0), restart(false)
00022 {
00023 }
00024 void clear()
00025 {
00026 restart = false;
00027 restart_key = HashKey();
00028 }
00029 }
00030 #ifdef __GNUC__
00031 __attribute__ ((aligned (64)))
00032 #endif
00033 ;
00034 volatile bool stop_all;
00035 CArray<ThreadData, 32> data;
00036 DfpnShared() : stop_all(false)
00037 {
00038 }
00039 void restartThreads(const HashKey& key, int depth, unsigned int threads)
00040 {
00041 for (int i=0; i<32; ++i)
00042 if ((1u << i) & threads) {
00043 SCOPED_LOCK(lk, data[i].mutex);
00044 if (! data[i].restart || data[i].depth > depth) {
00045 data[i].restart_key = key;
00046 data[i].depth = depth;
00047 data[i].restart = true;
00048 }
00049 }
00050 }
00051 void clear()
00052 {
00053 stop_all = false;
00054 for (size_t i=0; i<data.size(); ++i)
00055 data[i].clear();
00056 }
00057 };
00058 #ifdef OSL_DFPN_SMP
00059 class DfpnParallel : boost::noncopyable
00060 {
00061 private:
00062 DfpnTable *table;
00063 boost::scoped_array<Dfpn> workers;
00064 size_t num_threads;
00065
00066 const NumEffectState *state;
00067 HashKey key;
00068 PathEncoding path;
00069 Move last_move;
00070 size_t limit;
00071 struct WorkerData
00072 {
00073 Move best_move;
00074 PieceStand proof;
00075 ProofDisproof result;
00076 };
00077 boost::scoped_array<WorkerData> worker_data;
00078 DfpnShared shared;
00079 public:
00080 explicit DfpnParallel(size_t num_threads=0);
00081 ~DfpnParallel();
00082 void setTable(DfpnTable *new_table);
00083
00084 const ProofDisproof
00085 hasCheckmateMove(const NumEffectState& state, const HashKey& key,
00086 const PathEncoding& path, size_t limit, Move& best_move,
00087 Move last_move=Move::INVALID(), vector<Move> *pv=0);
00088 const ProofDisproof
00089 hasCheckmateMove(const NumEffectState& state, const HashKey& key,
00090 const PathEncoding& path, size_t limit, Move& best_move, PieceStand& proof,
00091 Move last_move=Move::INVALID(), vector<Move> *pv=0);
00092 const ProofDisproof
00093 hasEscapeMove(const NumEffectState& state,
00094 const HashKey& key, const PathEncoding& path,
00095 size_t limit, Move last_move);
00096
00097 size_t nodeCount() const;
00098 const DfpnTable& currentTable() const { return *table; }
00099 void analyze(const PathEncoding& path,
00100 const NumEffectState& state, const vector<Move>& moves) const;
00101
00102 void stopNow()
00103 {
00104 shared.stop_all = true;
00105 }
00106
00107 class AttackWorker;
00108 class DefenseWorker;
00109 friend class AttackWorker;
00110 friend class DefenseWorker;
00111 };
00112 #endif
00113 }
00114 }
00115
00116
00117 #endif
00118
00119
00120
00121